// ******************************************* // ** The Cowabunga Game (for Android) ** // ******************************************* // ** Written by Chadwick ** // ******************************************* package games.cowabunga; //** Running JavaWorld for Android... import android.image.*; import android.world.*; //** Android specific stuff... import android.app.Activity; import android.os.Bundle; import android.content.res.Resources; import games.cowabunga.R; // Represents the Android Application public class AndroidCowabunga extends Activity{ static Resources res; /** Called when the Activity is first created */ public void onCreate(Bundle savedState){ super.onCreate(savedState); AndroidCowabunga.res = this.getResources(); CowWorld start = new CowWorld(); start.bigBang(this); } } // Represents a Cartesian point, X/Y come from the // super class, Posn class CartPt extends Posn{ CartPt(int x, int y){ super(x,y); } // Move this CartPt by the given dX/dY CartPt move(int dx, int dy){ return new CartPt(this.x + dx, this.y + dy); } // Is this point (offset by dx) off the screen boolean offScreenX(int dx, int maxx){ return this.x < dx || maxx-dx < this.x; } // Is this point (offset by dy) off the screen boolean offScreenY(int dy, int maxy){ return this.y < dy || maxy-dy < this.y; } // Calculate the square of the given number double sqr(double d){ return d*d; } // Calculate the distance between this and that CartPt double dist(CartPt that){ return Math.sqrt(this.sqr(that.x-x) + this.sqr(that.y-y)); } } // Represents a simple Cow World class CowWorld extends World{ // Width/Height of the Scene int WIDTH = 320; int HEIGHT = 480; Scene initial = new EmptyScene(this.WIDTH, this.HEIGHT); Image grass = new Rectangle(this.WIDTH, 20, "solid", "darkgreen"); Cow cow; Ship alien; // Default constructor is a fresh Cow and Ship CowWorld(){ this.cow = new Cow(this.WIDTH/2, this.HEIGHT-36, true); this.alien = new Ship(this.WIDTH/2, 50); } // Initialize everything... CowWorld(Cow cow, Ship alien){ this.cow = cow; this.alien = alien; } // Draw this CowWorld, include the Cow, Ship, and Grass public Scene onDraw(){ return this.cow.place(this.alien.place(this.initial) .placeImage(this.grass, this.WIDTH/2, this.HEIGHT-10)); } // Move the Cow and the Ship, check for abduction public CowWorld onTick(){ return new CowWorld(this.cow.tick(this.WIDTH), this.alien.moveDown()); } // Move the Ship if an arrow key has been hit public CowWorld onKey(String ke){ if(ke.equals("down")){ return new CowWorld(this.cow, this.alien.moveDown()); }else if(ke.equals("left")){ return new CowWorld(this.cow, this.alien.moveHoriz(-10)); }else if(ke.equals("right")){ return new CowWorld(this.cow, this.alien.moveHoriz(10)); }else return this; } // Set the tick rate for the Cow world public double tickRate(){ return 0.04; } // Game ends when the Cow is abducted or the ship crashes public boolean stopWhen(){ return (this.cow.inRange(this.alien) || this.alien.crashed(this.HEIGHT-20)); } // Did the aliens Win? public boolean alienWins(){ return (this.cow.inRange(this.alien) && !this.alien.crashed(this.HEIGHT-20)); } // Return the message when the game's over String lastMessage(){ if(this.alienWins()) return "Abduction Success!"; else return "You Crashed!"; } // Last World, Win or Loose public Scene lastScene(){ return this.onDraw().placeImage(new Text(this.lastMessage(), 30, "black"), this.WIDTH/2, 100); } } // Represents a/the Cow class Cow{ // The size of the Cow's step int moveAmt = 5; // Images for a left and right moving Cow Image cowLeft = new FromResource(AndroidCowabunga.res, R.drawable.cowleft); Image cowRight = new FromResource(AndroidCowabunga.res, R.drawable.cowright); CartPt loc; boolean left; // Convenience constructor, give me X/Y Cow(int x, int y, boolean left){ this(new CartPt(x, y), left); } // Full constructor, takes a CartPt Cow(CartPt loc, boolean left){ this.loc = loc; this.left = left; } // Place this Cow into the given Scene Scene place(Scene scn){ if(left) return scn.placeImage(this.cowLeft, this.loc); else return scn.placeImage(this.cowRight, this.loc); } // Tick this Cow, move then maybe flip Cow tick(int maxx){ return this.move().flip(maxx); } // Make this Cow change direction if it hits the wall Cow flip(int maxx){ if(this.loc.offScreenX(this.cowLeft.width()/2, maxx)) return new Cow(this.loc, !this.left); else return this; } // Move this Cow in the direction it's going Cow move(){ if(left) return new Cow(this.loc.move(-this.moveAmt, 0), this.left); else return new Cow(this.loc.move(this.moveAmt, 0), this.left); } // Is this Cow within range of the Ship? boolean inRange(Ship s){ return s.inRange(this.loc); } } // Represents an Alien Ship class Ship{ Image ship = new FromResource(AndroidCowabunga.res, R.drawable.ship); Image shipCrash = new FromResource(AndroidCowabunga.res, R.drawable.shipcrash); int dropAmt = 3; CartPt loc; // Convenience Constructor Ship(int x, int y){ this(new CartPt(x, y)); } // Construct a Ship at the given location Ship(CartPt loc){ this.loc = loc; } // Place this Ship into the given Scene Scene place(Scene scn){ if(this.crashed(scn.height()-20)) return scn.placeImage(this.shipCrash, this.loc.move(0, -3)); else return scn.placeImage(new Triangle(this.ship.width()/2, "solid", "pink"), this.loc.move(0, this.ship.height())) .placeImage(this.ship, this.loc); } // Move/Float this Ship down Ship moveDown(){ return new Ship(this.loc.move(0, this.dropAmt)); } // Move/Float this Ship down Ship moveHoriz(int dx){ return new Ship(this.loc.move(dx, 0)); } // Did this ship crash? boolean crashed(int maxy){ return this.loc.offScreenY(this.ship.height()/2, maxy); } // Is this Ship within range of the Cow location? boolean inRange(CartPt cow){ return this.loc.dist(cow) < this.ship.width()/2; } }