Message Boards Message Boards

Raiden Arcade game

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. Here is a prototype of that:

enter image description here

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}, Row@{"Passed:", 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]
                 ]
               }]
  ]
Attachments:
POSTED BY: Baichuan Sun
3 Replies

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

POSTED BY: Sam Carrettie
POSTED BY: Baichuan Sun
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