Message Boards Message Boards

Raiden arcade game: an interactive classical shooter

enter image description here

There are a lot of arcade games realized with MMA, including: 2048 (2D and 3D), Sokoban, point 24, Gomoku, Snake, Minesweeper and Tetris. As well as video games like minecraft and SimCity 3000.

However, one classic scrolling shooter arcade game named "Raiden" (means "thunder and lighting") is missing.

Raiden is a 1990 vertically scrolling shooter arcade video game developed by Seibu Kaihatsu and published by Tecmo in Japan. The game's story takes place in the year 2090, when an alien species known as the Crystals invaded Earth. Players assume the roles of the Vanquish Crystal Defense pilot duo, taking control of two state of the art Fighting Thunders aircraft to defeat the Crystals and save the Earth.

Here is a prototype of that:

ClearAll["Global`*"]
ClearSystemCache[]
RemoveScheduledTask[ScheduledTasks[]];
DynamicModule[
  {
        army = {},
        bullet = {},
        missle = {},
        direct = {},
        reach = 0,
        score = 0,

        toClean,
        num = 5,
        pos,
        (*reach=0,*)
        reachNum = 10,

        RestartAll,
        pausing = True,
        stop = True,

        rand,
        least,
        launcher,
        target,

        hit,
        explosion = 10,
        crash = 10,

        bulletSpeed = .6,
        enermySpeed = .1,

        jet = Graphics[
               {Darker@Blue, Polygon[{{0, 0}, {1, 0}, {1, .1}, {0, .1}}],
             Polygon[{{0.5, 2}, {.4, .6}, {.6, .6}}],
             Polygon[{{-1, 1}, {2, 1}, {.5, 1.2}}],
             Thickness -> .02, Arrow[{{.2, .1}, {.2, 1.5}}],
             Arrow[{{.8, .1}, {.8, 1.5}}]}, ImageSize -> Tiny],

        enermy = Graphics[
               {Gray, Polygon[{{.1, 2}, {.9, 2}, {.9, 1.9}, {.1, 1.9}}],
             Polygon[{{.5, 0}, {.4, 1.9}, {.6, 1.9}}],
             Polygon[{{-1, 1.1}, {2, 1.1}, {.5, .9}}],
             Thickness -> .02, Arrow[{{.2, 1.4}, {.2, 0.6}}],
             Arrow[{{.8, 1.4}, {.8, .6}}]}, ImageSize -> Tiny]
    },
    least[bullets_, army_] :=(*Get the local (pseduo) minimum distance between bullets and enermy army*)
           Module[{len1 = Length@bullets, len2 = Length@army, frontList, postList, dist, loc, short, long, locShort, locLong},
             If[len1 >= len2, frontList = bullets; postList = army, frontList = army; postList = bullets];
             dist = (EuclideanDistance @@@ Partition[Riffle[frontList, postList], 2, 1]);
             loc = First@Flatten@Position[dist, Min[dist], 1(*,1*)];
             locShort = Mod[Mod[loc, 2] + Quotient[loc, 2], Length@postList, 1];
             locLong = Quotient[loc, 2] + 1;
             short = postList[[locShort]];
             long = frontList[[locLong]];
             Return[If[len1 >= len2, {locShort, locLong, Min@dist}, {locLong, locShort, Min@dist}]]
         ];

    rand[] := {RandomReal[{-30, 40}], 160};(*Randomly generate enermy flights*)

    RestartAll[] := (RemoveScheduledTask[ScheduledTasks[]];
        RunScheduledTask[
               If[! pausing,

             If[(*Randomly generate enermy flights*)
                     MemberQ[
                        RandomChoice[
                              {(Length@army)/num, 1 - (Length@army)/num} -> {False, True},
                              1
                          ],
                     True],
                   AppendTo[army, {enermy, rand[]}]
                   ];
             If[(*Handle the situate of collision between the jet and enermy army*)
                     MemberQ[
                        Norm[
                                  #[[2]] - MousePosition["Graphics", {0, 0}]
                                ] < crash & /@ army,
                     True],
                     (*Speak["Bang"];*)
                     RemoveScheduledTask[ScheduledTasks[]];
                     CreateDialog[{TextCell["You Crash!", "Title"], Column@{Row@{"Score: ", score}, Row@{"Passed:", reach}}, DefaultButton[]}]
                   ];
             If[(*Handle the situate of enermy army be hit by our bullets*)
                     Length@army > 0 \[And] Length@bullet > 0,
                     hit = least[bullet, army[[All, 2]]];
                     (*Print[hit];*)
                     If[
                        Last@hit < explosion,
                        score += 10;
                        army = Delete[army, First@hit];
                        bullet = Delete[bullet, hit[[2]] ]
                     ]
                   ];
             If[(*enermy gives out missles*)
                     Length@army > 0 && RandomReal[] > .05,
                     launcher = RandomChoice@army[[All, 2]];
                     (AppendTo[missle, launcher];
                     AppendTo[direct, Normalize[-launcher + MousePosition["Graphics", {0, 0}]]]);
                   ];
             If[(*Handle the situate of being hit*)
                     MemberQ[
                        Norm[
                                  # - MousePosition["Graphics", {0, 0}]
                                ] < crash & /@ missle,
                     True],
                     RemoveScheduledTask[ScheduledTasks[]];
                     CreateDialog[{TextCell["You are hit!", "Title"], Column@{Row@{"Score: ", score}, Row@{"Passed:", reach}}, DefaultButton[]}]
                   ];
             If[(*If more than reachNum of enermies reach the bottom, lose the game*)
                   reach >= reachNum,
                   RemoveScheduledTask[ScheduledTasks[]];
                   CreateDialog[{TextCell["You Lost the Base!", "Title"], Column@{Row@{"Score: ", score},ed:", reach}}, DefaultButton[]}]
                   ];

             ];

            1
            ]);

    Panel[ Column@{
               Column@{Row@{Text[Style["score: ", Black, 18]], Text[Style[Dynamic[score], Orange, 16]]},
                   Row@{Text[Style["passed:", Black, 18]], Text[Style[Dynamic[reach], Orange, 16]],
                         Text[Style["/", Orange, 16]], Text[Style[reachNum, Orange, 16]]},
                   Button[
                     Dynamic[If[! stop, "Restart", "Start"]],
                     RestartAll[];
                     stop = pausing = False;
                     score = 0; reach = 0],
                   Button[
                     Dynamic[If[! pausing, "Cease", "Resume"]],
                        If[pausing, pausing = False, pausing = True],
                        Enabled -> Dynamic[! stop]],
                   Dynamic[Text[Style[If[! stop, If[! pausing, "fighting", "pausing"], "Stop"], Black, 16]]]},

               MouseAppearance[
                 EventHandler[
                      Labeled[Deploy@Framed@Graphics[{
                                PointSize[Large],

                                Blue,
                                Dynamic[
                                      Point[(bullet[[All, 2]] += bulletSpeed(*.5*); bullet = Select[bullet, #[[2]] < 150 &]; bullet)], TrackedSymbols :> {bullet}(*Handle the bullets*)
                                  ],

                                Red,
                                Dynamic[
                                      Point[
                                       (
                                             pos = Position[missle, #] & /@ Select[missle, #[[1]] < -50 || #[[1]] > 50 || #[[2]] > 150 || #[[2]] < 10 &, 1];
                                             If[Length@pos > 0,
                                           toClean = # & @@ pos;
                                           (*Print[toClean];*)
                                           missle = Delete[missle, toClean];
                                           direct = Delete[direct, toClean]];
                                             missle += .5 direct)
                                      ],
                                      TrackedSymbols :> {missle}(*Handle the missles*)
                                  ],


                                  Dynamic[Thread[Inset[(*Handle the enermy army*)
                                                 Magnify[enermy, .5], #
                                              ] &[
                                               If[! pausing, reach += Length@Select[army, #[[2, 2]] < 5 &]];
                                               army = Select[army, #[[2, 2]] > 5 &];
                                               army[[All, 2, 2]] -=(*.4*)enermySpeed;
                                               army[[All, 2]]
                                             ]],
                                      TrackedSymbols :> {army}]

                             },
                              PlotRange -> {{-50, 50}, {0, 150}},
                              ImageSize -> 300
                             ], Text[Style["Thunder & Lighting", Darker@Green, Italic, 24]], Top],
                   {"MouseClicked" :> {(*Speak["Shu"];*)AppendTo[bullet, MousePosition["Graphics", {0, 0}]]}}(*Shoot on Mouse Click Action*)
                   ],
             Magnify[jet, .5]
                 ]
               }]
  ]
POSTED BY: Baichuan Sun
4 Replies

enter image description here -- you have earned Featured Contributor Badge enter image description here Your exceptional post has been selected for our editorial column Staff Picks http://wolfr.am/StaffPicks and Your Profile is now distinguished by a Featured Contributor Badge and is displayed on the Featured Contributor Board. Thank you!

POSTED BY: Moderation Team

Amazing, i wrote a couple of shmups myself in my good old days, i really miss those (i prefered horizontal scrollers but they are very rare) ! There were laser beams with bezier splines, that was pretty neat for its era :)

Unfortunately it doesn't support today's computers anymore. It's very Galaga inspired ( you could even connect 2 ships)

enter image description here

Hi Sam, Thanks for the comments. I only tested the code under MMA 9.0 and 10, as I do not have 10.1 near hand. Any improvement on the code and algorithm is welcomed. The Github linkage is:

https://github.com/sunbc0120/Raiden

I was born at 1980s, so I'm a big fan of Arcade games:)

POSTED BY: Baichuan Sun

This is nicely done. Did you write this one? BTW on Mathematica 10.1 "Restart" did not do anything - I could not shoot. But otherwise this is a cool idea, indeed Arcade games are awesome.

Raiden ( ?? ) is a 1990 scrolling shooter arcade game that was developed by Seibu Kaihatsu. It was the first game in the Raiden series of scrolling shooter arcade games. Raiden was released in September 1990. The game was distributed in Japan by Tecmo, North America by Fabtek, Taiwan by Liang HWA Electronics, Korea by IBL Corporation, Hong Kong by Wah Yan Electronics, and a few other countries such as Malaysia, though the publishers in those countries are unknown.

Due to the success of Raiden, several sequels and related games were made. ~ Wikipedia

POSTED BY: Sam Carrettie
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract