commit b00f8d7d87e33dcfa6279c6242a9d534cf285e52 Author: Cody T Date: Wed Apr 15 19:50:15 2026 -0500 initial commit diff --git a/Amendment.java b/Amendment.java new file mode 100644 index 0000000..5908b66 --- /dev/null +++ b/Amendment.java @@ -0,0 +1,10 @@ +import javax.swing.ImageIcon; + + +public class Amendment extends Collectable{ + + public Amendment(int x, int y, int w, int h){ + super(x,y,w,h,new ImageIcon("Sprites/Amendment.png")); + } + +} \ No newline at end of file diff --git a/Brick.java b/Brick.java new file mode 100644 index 0000000..f4c12c1 --- /dev/null +++ b/Brick.java @@ -0,0 +1,8 @@ +import javax.swing.ImageIcon; + +public class Brick extends Tile { + + public Brick(int x, int y, int w, int h){ + super(x,y,w,h,new ImageIcon("Sprites/Bricks/Brick.png")); + } +} \ No newline at end of file diff --git a/Collectable.java b/Collectable.java new file mode 100644 index 0000000..e1bbdce --- /dev/null +++ b/Collectable.java @@ -0,0 +1,8 @@ +import java.awt.Rectangle; +import javax.swing.ImageIcon; + +public class Collectable extends Collidable{ + public Collectable(int x, int y, int w, int h,ImageIcon i){ + super(x,y,w,h,i); + } +} \ No newline at end of file diff --git a/Collidable.java b/Collidable.java new file mode 100644 index 0000000..1e92fae --- /dev/null +++ b/Collidable.java @@ -0,0 +1,30 @@ +import java.awt.Rectangle; +import javax.swing.ImageIcon; +import java.awt.Graphics; + +public class Collidable extends Sprite{ + int x,y,width,height; + Rectangle rect; + + public Collidable(int x1, int y1, int w, int h, ImageIcon icon){ + super(icon); + x = x1; + y = y1; + width = w; + height = h; + rect = new Rectangle(x1,y1,w,h); + } + + public void draw(Graphics g){ + sprite = icon.getImage(); + g.drawImage(sprite, x, y, width, height, null); + } + + public boolean collidesWith(Collidable other) { + return this.rect.intersects(other.rect); + } + + public void onCollide(Collidable other){ + return; + } +} \ No newline at end of file diff --git a/Display.java b/Display.java new file mode 100644 index 0000000..9ed4dab --- /dev/null +++ b/Display.java @@ -0,0 +1,22 @@ +import javax.swing.*; +import java.awt.Color; + +public class Display { + public static void main(String[] args) { + int boardWidth = 800; + int boardHeight = 800; + int tileSize = 20; + + JFrame game = new JFrame(); + game.setSize(boardWidth, boardHeight); + game.setVisible(true); + game.setLocationRelativeTo(null); + game.setResizable(false); + + + Platformer platformer = new Platformer(boardWidth, boardHeight, tileSize); + game.add(platformer); + game.pack(); + platformer.requestFocus(); + } +} \ No newline at end of file diff --git a/Enemy.java b/Enemy.java new file mode 100644 index 0000000..1a197aa --- /dev/null +++ b/Enemy.java @@ -0,0 +1,53 @@ +import javax.swing.ImageIcon; +import java.util.*; +public class Enemy extends Collidable{ + int xVelo, yVelo; + boolean alive; + + public Enemy(int x, int y, int w, int h, int level){ + super(x,y,w,h,new ImageIcon("Sprites/Enemies/" + level + ".png")); + xVelo = 2; + yVelo = 0; + alive = true; + } + + public void moveX(int moveX){ + this.x += moveX; + this.rect.x = this.x; + } + + public void moveY(int moveY){ + this.y += moveY; + this.rect.y = this.y; + } + + public void patrol(ArrayList collidables){ + moveX(xVelo); + + for (Collidable c : collidables){ + if (this.collidesWith(c)){ + xVelo = -xVelo; + moveX(xVelo * 2); + break; + } + } + + // check edge detection - is there ground below next step? + boolean edgeAhead = true; + int nextX = this.x + xVelo; + for (Collidable c : collidables) { + if (c instanceof Tile) { + Tile t = (Tile) c; + // check if tile is below enemy's next position + if (nextX + this.width > t.x && nextX < t.x + t.width && + t.y == this.y + this.height) { + edgeAhead = false; + break; + } + } + } + if (edgeAhead) { + xVelo = -xVelo; + } + } +} \ No newline at end of file diff --git a/Flag.java b/Flag.java new file mode 100644 index 0000000..feb0536 --- /dev/null +++ b/Flag.java @@ -0,0 +1,15 @@ +import javax.swing.ImageIcon; + +public class Flag extends Collidable { + public Flag(int x, int y, int w, int h) { + super(x, y, w, h, new ImageIcon("Sprites/Flag.png")); + } + + public void setPosition(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.width = w; + this.height = h; + this.rect.setBounds(x, y, w, h); + } +} \ No newline at end of file diff --git a/LevelLoader.java b/LevelLoader.java new file mode 100644 index 0000000..e7cf52a --- /dev/null +++ b/LevelLoader.java @@ -0,0 +1,42 @@ +import javax.swing.ImageIcon; +import java.util.*; +import java.io.*; + +public class LevelLoader { + static int enemyWidth[] = {0,31,20,20,20,20,20,29,29,20,20}; + static int enemyHeight[] = {0,20,20,20,20,20,20,20,20,20,20}; + + public static void load(int tileSize, + ArrayList collidables, + ArrayList collectables, + ArrayList enemies, + Flag flag, + Player player, int level) throws IOException { + collidables.clear(); + collectables.clear(); + enemies.clear(); + + /*left wall*/ collidables.add(new Brick(-20,0,20,2000)); + + BufferedReader br = new BufferedReader(new FileReader("Levels/level" + level + ".txt")); + String line; + int row = 0; + while ((line = br.readLine()) != null) { + for (int col = 0; col < line.length(); col++) { + char c = line.charAt(col); + int x = col * tileSize; + int y = row * tileSize; + switch(c) { + case 'B': collidables.add(new Brick(x, y, tileSize, tileSize)); break; + case 'Q': collidables.add(new PowerBrick(x, y, tileSize, tileSize, 1)); break; + case 'A': collectables.add(new Amendment(x, y, tileSize, tileSize)); break; + case 'F': flag.setPosition(x, y, tileSize, tileSize); break; + case 'P': player.x = x; player.y = y; player.rect.x = x; player.rect.y = y; break; + case 'E': enemies.add(new Enemy(x,y,enemyWidth[level],enemyHeight[level],level)); break; + } + } + row++; + } + br.close(); + } +} \ No newline at end of file diff --git a/Levels/level1.txt b/Levels/level1.txt new file mode 100644 index 0000000..307d0cd --- /dev/null +++ b/Levels/level1.txt @@ -0,0 +1,20 @@ +.................................................................................................... +.................................................................................................... +.................................................................................................... +.................................................................................................... +.................................................................................................... +.................................................................................................... +.................................................................................................... +.................................................................................................... +.................................................................................................... +................................................................................ +. +. +. +.................................................. +..............................BBBBB....BBBBB..................................A.......................... +............A.......BBBBB........................BBBBB.......BBBBB.........BBQBB................................... +..........BBBBB.......................................................................BBBBB.............. +.................................................................................................... +.P........................A........E...................E...A...............E.....................F.. +BBBBBBBBBBBBBBBBBBBB..BBBBBBBBBBBBBBBBBBBBBBB..BBBBBBBBBBBBBBBBBBBBBBB..BBBBBBBBBBBBBBBBBBBBBBBBBBBB \ No newline at end of file diff --git a/Levels/level10.txt b/Levels/level10.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level10.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level2.txt b/Levels/level2.txt new file mode 100644 index 0000000..ea68da3 --- /dev/null +++ b/Levels/level2.txt @@ -0,0 +1,39 @@ +.................................................................................................... +...................................................... +. +. +. +. + +. +. +. +. +. +. +...............................................................................................A........................... +............................................................................................BBBBBB........... +..........................................................................BBBBBB +........................................................................ +............................................................A............ +..........................................................BBBBB +....................................................... +..................................................................................................................A +............................................BBBBB....................................................... +.................................BBBBB.............................................................. +...........................A......................................................................... +.........................BBBBB........................................................................ +.................................................................................................... +.................BBBBB................................................................................... +.................................................................................................... +............................................................................................. +............................................................................................. +................................................................. +. +. +................................................. +........BBBBB.............A.................................................................... +.........................QBQQQQQBBBB +.................................................................................................... +.P.............E..............E...................E............................................................F.. +BBBBBBBBBBBBBBBBBB...BBBBBBBBBBBBBBBBB...BBBBBBBBBBBBBBBBBBB...BBBBBBB......................................BBBBBBBBBBBBBBBBBBBB \ No newline at end of file diff --git a/Levels/level3.txt b/Levels/level3.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level3.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level4.txt b/Levels/level4.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level4.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level5.txt b/Levels/level5.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level5.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level6.txt b/Levels/level6.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level6.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level7.txt b/Levels/level7.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level7.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level8.txt b/Levels/level8.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level8.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Levels/level9.txt b/Levels/level9.txt new file mode 100644 index 0000000..799835f --- /dev/null +++ b/Levels/level9.txt @@ -0,0 +1,20 @@ +................................. +................................. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +...P +...............E +BBBBBBBB..BBBBBBBBBB \ No newline at end of file diff --git a/Platformer.java b/Platformer.java new file mode 100644 index 0000000..8950917 --- /dev/null +++ b/Platformer.java @@ -0,0 +1,474 @@ +import java.util.Random; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.io.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Graphics; +import javax.swing.*; +import java.time.LocalTime; + + +public class Platformer extends JPanel implements KeyListener, ActionListener{ + + //constants + static final int GRAVITY = 1; + static final Color playerColor = Color.RED; + static final Color tileColor = Color.BLUE; + static final Color SKY = new Color(135, 206, 235); + static final int FRICTION = 1; + static final int MAXYVELO = 15; + static final int MAXXVELO = 5; + static final int totalLevels = 10; + static int[] numAm = {4,5,0,0,0,0,0,0,0,0}; + + //game objects + Player player; + ArrayList collidables; + ArrayList collectables; + Flag flag; + ArrayList enemies; + ArrayList projectiles; + + //game vars + int boardWidth; + int boardHeight; + int tileSize; + Timer gameTimer; + HashMap pressedKeys; + boolean jumpPressed; + int cameraX, cameraY; + int currentLevel; + boolean allCollected; + boolean gameOver; + boolean gameStarted; + Image heart,emptyHeart,slash,amendmentImg,powerImg,startImg; + ArrayList numbers; + + + public Platformer(int boardWidth, int boardHeight, int tileSize){ + //setup game + this.boardWidth = boardWidth; + this.boardHeight = boardHeight; + this.tileSize = tileSize; + setPreferredSize(new Dimension(this.boardWidth, this.boardHeight)); + addKeyListener(this); + this.setFocusable(true); + this.setLayout(null); + + + pressedKeys = new HashMap<>(); + jumpPressed = false; + gameOver = false; + gameStarted = false; + setBackground(SKY); + + //setup objects + heart = new ImageIcon("Sprites/Hearts/heart.png").getImage(); + emptyHeart = new ImageIcon("Sprites/Hearts/emptyHeart.png").getImage(); + startImg = new ImageIcon("Sprites/start.png").getImage(); + gameTimer = new Timer(15,this); + player = new Player(-20,0,tileSize,tileSize); + collidables = new ArrayList<>(); + collectables = new ArrayList<>(); + enemies = new ArrayList<>(); + projectiles = new ArrayList<>(); + flag = new Flag(-20,0,tileSize,tileSize); + cameraX = 0; + cameraY = 0; + currentLevel = 0; + numbers = new ArrayList<>(); + for (int i =0; i < 10; i++) numbers.add((new ImageIcon("Sprites/Numbers/" + i + ".png")).getImage()); + slash = new ImageIcon("Sprites/Numbers/Slash.png").getImage(); + amendmentImg = new ImageIcon("Sprites/Amendment.png").getImage(); + powerImg = new ImageIcon("Sprites/Powerup1.png").getImage(); + + gameTimer.start(); + + + //if i wanna add a button + /*JButton gameStart = new JButton("Start Game"); + gameStart.addActionListener(e -> { + loadLevel(currentLevel); + gameTimer.start(); + this.remove(gameStart); + this.revalidate(); + this.repaint(); + }); + gameStart.setBorderPainted(false); + gameStart.setFocusPainted(false); + gameStart.setBounds(193,200,114,15); + gameStart.setForeground(new Color(52, 152, 219)); + this.add(gameStart);*/ + } + + //gameloop + public void gameLoop(){ + //camera + cameraX = player.x - boardWidth / 2; + cameraX = Math.max(0, cameraX); + cameraY = player.y - boardHeight / 2; + //cameraY = Math.max(0, cameraY); + + + + //win + allCollected = player.numAmendments >= numAm[currentLevel-1]; + if (player.collidesWith(flag) && allCollected) { + currentLevel++; + player.health = 3; + if (currentLevel > totalLevels) { + gameTimer.stop(); + System.out.println("You win!"); + } else { + loadLevel(currentLevel); + } + return; + } + + //keys + if (Math.abs(player.xVelo) < MAXXVELO){ + if(isKeyPressed(KeyEvent.VK_D) || isKeyPressed(KeyEvent.VK_RIGHT)){ + player.xVelo += 1; + } + else if(isKeyPressed(KeyEvent.VK_A) || isKeyPressed(KeyEvent.VK_LEFT)){ + player.xVelo -= 1; + } + + } + if (!isKeyPressed(KeyEvent.VK_D) && !isKeyPressed(KeyEvent.VK_RIGHT) && !isKeyPressed(KeyEvent.VK_A) && !isKeyPressed(KeyEvent.VK_LEFT)){ //friction + if (player.xVelo > 0){ + player.xVelo = Math.max(0, player.xVelo - FRICTION); + } + else if (player.xVelo < 0){ + player.xVelo = Math.min(0, player.xVelo + FRICTION); + } + } + + //jump + boolean jumpKeyDown = (isKeyPressed(KeyEvent.VK_W) || isKeyPressed(KeyEvent.VK_UP)); + if(jumpKeyDown && !jumpPressed){ + if(player.onGround){ + player.yVelo = -15; + player.onGround = false; + jumpPressed = true; + player.airJumps = 0; + } + else if (player.curPower == 1 && player.airJumps < 1){ + player.yVelo = -15; + player.airJumps++; + jumpPressed = true; + } + } + if (!jumpKeyDown){ + jumpPressed = false; + } + + //gravity + if (player.yVelo < MAXYVELO){ + player.yVelo += GRAVITY; + } + + //fall out of world + if (player.y > boardHeight){ + loadLevel(currentLevel); + player.health--; + } + + for (Collectable c : collectables){ + if (c instanceof Powerup){ + Powerup pu = (Powerup) c; + if (pu.yVelo < MAXYVELO && !pu.onGround){ + pu.yVelo += GRAVITY; + } + pu.moveY(pu.yVelo); + for (Collidable col : collidables) { + if (pu.collidesWith(col)) { + pu.yVelo = 0; + pu.onGround = true; + pu.y = ((Tile)col).y - pu.height; + pu.rect.y = pu.y; + } + } + if (player.collidesWith(pu)) { + player.curPower = pu.id; + player.powerTimer = Player.POWER_DURATION; + } + } + else if (c instanceof Amendment){ + Amendment am = (Amendment) c; + if (player.collidesWith(am)){ + player.numAmendments++; + } + } + } + collectables.removeIf(c -> player.collidesWith(c)); + + //update x + player.moveX(player.xVelo); + + //collision with all tiles x + for (Collidable c : collidables) { + if (player.collidesWith(c)) { + player.onCollideX(c); + } + } + + //update y + player.moveY(player.yVelo); + //assume not on ground + player.onGround = false; + + //collision with all tiles y + for (Collidable c : collidables) { + if (player.collidesWith(c)) { + player.onCollideY(c,collectables); + } + } + + + + //Powerup timer + if (player.curPower > 0) { + player.powerTimer--; + if (player.powerTimer <= 0) { + player.curPower = 0; + } + } + + //update facing + if (player.xVelo > 0) player.facing = 1; + else if (player.xVelo < 0) player.facing = -1; + + // shoot cooldown + if (player.shootCooldown > 0) player.shootCooldown--; + + // invincibility timer + if (player.invincibleTimer > 0) player.invincibleTimer--; + + //shoot + //projectiles + if (isKeyPressed(KeyEvent.VK_SPACE) && player.shootCooldown == 0){ + int projX = player.facing == 1 ? player.x + player.width : player.x - 10; + projectiles.add(new Projectile(projX,player.y,tileSize,10,currentLevel,player.facing)); + player.shootCooldown = Player.SHOOT_COOLDOWN; + } + + projectiles.removeIf(p -> p.x < -50 + cameraX || p.x > boardWidth + cameraX + 200); + for (Projectile p : new ArrayList<>(projectiles)) { + p.move(); + // projectile hits tile + for (Collidable c : collidables) { + if (p.collidesWith(c)) { + projectiles.remove(p); + break; + } + } + } + + + // update enemies + for (Enemy e : enemies) { + e.patrol(collidables); + // enemy hits player + if (player.collidesWith(e)) { + player.takeDamage(); + } + } + + //die + if (player.health <= 0) { + System.out.print("Game Over - You Died!"); + gameOver = true; + gameTimer.stop(); + } + + //projectile hits enemy + for (Projectile p : new ArrayList<>(projectiles)){ + for (Enemy e : new ArrayList<>(enemies)){ + if (p.collidesWith(e)) { + enemies.remove(e); + projectiles.remove(p); + break; + } + } + } + enemies.removeIf(e -> !e.alive); + } + + public void loadLevel(int level) { + projectiles.clear(); + try { + LevelLoader.load(tileSize, collidables, collectables, enemies, flag, player, level); + player.reset(); + player.setLevel(level); + cameraX = 0; + cameraY = 0; + } catch (IOException e) { + System.out.println("Could not load level " + level); + } + } + + //paintComponent + public void paintComponent(Graphics g){ + super.paintComponent(g); + draw(g); + } + + //draw function + public void draw(Graphics g){ + g.translate(-cameraX, -cameraY); + + player.draw(g); + for (Collidable c : collidables) c.draw(g); + for (Collectable c : collectables) c.draw(g); + for (Enemy e : enemies) e.draw(g); + for (Projectile p : projectiles) p.draw(g); + flag.draw(g); + + //flag counter + int amOnes = player.numAmendments % 10; + int amTens = player.numAmendments / 10; + + if (currentLevel > 0 && !gameOver && player.numAmendments < numAm[currentLevel-1]){ + if (amTens > 0) g.drawImage(numbers.get(amTens),flag.x-20,flag.y-30,null); + g.drawImage(numbers.get(amOnes),flag.x+5,flag.y-30,null); + g.drawImage(slash,flag.x+28,flag.y-32,null); + g.drawImage(numbers.get(numAm[currentLevel-1]),flag.x+55,flag.y-30,null); + g.drawImage(amendmentImg,flag.x+85,flag.y-30,null); + } + + g.translate(cameraX, cameraY); + + + int modAmt = 2000; + int curTime = (int) System.currentTimeMillis() % modAmt; + curTime = Math.abs(curTime); + + //start screen + int startTime = 0; + if (curTime >= 0 && curTime <= modAmt/4-1) startTime = 0; + else if (curTime >= modAmt/4 && curTime <= modAmt/2-1) startTime = 1; + else if (curTime >= modAmt/2 && curTime <= modAmt*3/4-1) startTime = 2; + else if (curTime >= modAmt*3/4 && curTime <= modAmt-1) startTime = 3; + + if (currentLevel == 0 && !gameOver){ + g.drawImage(startImg,340,300,null); + + String text = "Press P to Start!"; + int xBase = 340; + int yBase = 400; + int spacing = 8; + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + + // x moves linearly + int x = xBase + (i * spacing); + + // y uses a sine wave + // Math.sin takes radians. We use (startTime + i) to give each letter a different phase. + double waveOffset = Math.sin(startTime + i * 0.5) * 10; + int y = yBase + (int)waveOffset; + + g.drawString(String.valueOf(c), x, y); + } + } + + if (currentLevel > 0 && !gameOver){ + + //draw hearts: + int heartTime = 0; + if (curTime >= 0 && curTime <= modAmt/2-1) heartTime = 1; + else if (curTime >= modAmt/2 && curTime <= modAmt-1) heartTime = 0; + for (int i = 0; i < player.health; i++){ + g.drawImage(heart,(((i+1) * 20)-10)+heartTime,10+heartTime * 2,null); + } + for (int i =0; i < 3 - player.health; i++){ + g.drawImage(emptyHeart,(50 - (i * 20)) + heartTime,10+heartTime * 2,null); + } + + //draw amendments counter in top right + + if (amTens > 0) g.drawImage(numbers.get(amTens),315,10,null); + g.drawImage(numbers.get(amOnes),340,10,null); + g.drawImage(slash,363,12,null); + g.drawImage(numbers.get(numAm[currentLevel-1]),390,10,null); + g.drawImage(amendmentImg,420,10,null); + + + //draw powerup timer + if (player.curPower == 1){ + int secs = player.powerTimer/66; + int tens = secs/10; + int ones = secs%10; + if (tens > 0){ + g.drawImage(numbers.get(tens),184,10,null); + } + g.drawImage(numbers.get(ones),205,10,null); + g.drawImage(powerImg,220,10,null); + } + } + + //gameover screen + if (gameOver){ + + } + } + + //is key pressed + public boolean isKeyPressed(int key){ + return pressedKeys.getOrDefault(key,false); + } + + //every tick + @Override + public void actionPerformed(ActionEvent e){ + if (gameStarted) { + gameLoop(); + } + repaint(); + } + + //check for key presses + @Override + public void keyPressed(KeyEvent e){ + if (e.getKeyCode() == KeyEvent.VK_P){ + if(currentLevel == 0) { + currentLevel = 1; + loadLevel(currentLevel); + gameStarted = true; + } + gameTimer.start(); + return; + } + + if (e.getKeyCode() == KeyEvent.VK_R){ + gameTimer.stop(); + loadLevel(currentLevel); + jumpPressed = false; + player.health=3; + gameOver = false; + repaint(); + return; + } + + if (e.getKeyCode() == KeyEvent.VK_O){ + currentLevel++; + loadLevel(currentLevel); + } + + pressedKeys.put(e.getKeyCode(),true); + } + + @Override + public void keyReleased(KeyEvent e){ + pressedKeys.put(e.getKeyCode(),false); + } + + //dont need + @Override + public void keyTyped(KeyEvent e){ + + } +} \ No newline at end of file diff --git a/Player.java b/Player.java new file mode 100644 index 0000000..5b22986 --- /dev/null +++ b/Player.java @@ -0,0 +1,109 @@ +import javax.swing.ImageIcon; +import java.util.*; +public class Player extends Collidable { + + static final int JUMP_HEIGHT = 10; + static final int POWER_DURATION = 2000; // 2000 ticks ≈ 30 seconds + static final int I_FRAMES = 67; // ~1 second + static final int SHOOT_COOLDOWN = 33; //~0.5 second + + int health; + int yVelo; + int xVelo; + boolean onGround; + int curPower; + int powerTimer; + int airJumps; + int facing; // 1 is right -1 is left + int invincibleTimer; + int shootCooldown; + int numAmendments; + + public Player(int x, int y, int w, int h){ + super(x,y,w,h,new ImageIcon("Sprites/Player/1.png")); + xVelo = 0; + yVelo = 0; + onGround = false; + curPower = 0; + powerTimer = 0; + airJumps = 0; + invincibleTimer = 0; + shootCooldown = 0; + health = 3; + facing = 1; + numAmendments = 0; + } + + public void moveX(int moveX){ + this.x += moveX; + this.rect.x = this.x; + } + + public void moveY(int moveY){ + this.y += moveY; + this.rect.y = this.y; + } + + public void setLevel(int level){ + this.icon = new ImageIcon("Sprites/Player/" + level + ".png"); + } + + public void onCollideX(Collidable other){ + if (other instanceof Tile){ + Tile t = (Tile) other; + int playerCenterX = this.x + this.width / 2; + int tileCenterX = t.x + t.width / 2; + if (playerCenterX > tileCenterX) { //player on right side of tiile + this.x = t.x + t.width; + } + else { //player on left side of tile + this.x = t.x - this.width; + } + this.xVelo = 0; + this.rect.x = this.x; + } + } + + public void onCollideY(Collidable other, ArrayList collectables){ + if (other instanceof Tile){ + Tile t = (Tile) other; + if (this.yVelo >= 0) { // falling down, land on top of tile + this.y = t.y - this.height; + onGround = true; + airJumps = 0; + } + else { // moving up, hit underside of tile + this.y = t.y + t.height; + if (other instanceof PowerBrick){ + PowerBrick pb = (PowerBrick) other; + if(!pb.hit){ + pb.spawnPower(collectables); + } + } + } + this.yVelo = 0; + this.rect.y = this.y; + } + } + + public void takeDamage() { + if (invincibleTimer <= 0) { + health--; + invincibleTimer = I_FRAMES; + } + } + + public void reset(){ + this.rect.x = this.x; + this.rect.y = this.y; + this.xVelo = this.yVelo = 0; + this.curPower = 0; + this.powerTimer = 0; + this.airJumps = 0; + this.onGround = false; + this.invincibleTimer = 0; + this.shootCooldown = 0; + this.facing = 1; + this.numAmendments = 0; + } +} \ No newline at end of file diff --git a/PowerBrick.java b/PowerBrick.java new file mode 100644 index 0000000..a995f43 --- /dev/null +++ b/PowerBrick.java @@ -0,0 +1,26 @@ +import java.awt.Graphics; +import java.awt.Color; +import javax.swing.ImageIcon; +import java.util.*; + +public class PowerBrick extends Tile{ + int id; + boolean hit; + + public PowerBrick(int x, int y, int w, int h, int id) { + super(x, y, w, h, new ImageIcon("Sprites/Bricks/PowerBrick.png")); + this.id = id; + hit = false; + } + + public void spawnPower(ArrayList powerups){ + this.icon = new ImageIcon("Sprites/Bricks/EmptyBrick.png"); + hit = true; + powerups.add(new Powerup(this.x, this.y - this.height, this.width, this.height, 1)); + } + + public void reset(){ + hit = false; + this.icon = new ImageIcon("Sprites/Bricks/PowerBrick.png"); + } +} \ No newline at end of file diff --git a/Powerup.java b/Powerup.java new file mode 100644 index 0000000..ba292fc --- /dev/null +++ b/Powerup.java @@ -0,0 +1,25 @@ +import javax.swing.ImageIcon; +import javax.swing.Timer; +import java.util.*; + +public class Powerup extends Collectable{ + int yVelo, xVelo, id; + boolean onGround; + + public Powerup(int x, int y, int w, int h, int id){ + super(x,y,w,h,new ImageIcon("Sprites/Powerup" + id + ".png")); + xVelo = 0; yVelo = -7; + onGround = false; + this.id = id; + } + + public void moveX(int moveX){ + this.x += moveX; + this.rect.x = this.x; + } + + public void moveY(int moveY){ + this.y += moveY; + this.rect.y = this.y; + } +} \ No newline at end of file diff --git a/Projectile.java b/Projectile.java new file mode 100644 index 0000000..aeb70e3 --- /dev/null +++ b/Projectile.java @@ -0,0 +1,15 @@ +import javax.swing.ImageIcon; + +public class Projectile extends Collidable { + int xVelo; + + public Projectile(int x, int y, int w, int h, int curLevel, int direction){ + super(x,y,w,h,new ImageIcon("Sprites/Projectiles/" + curLevel + ".png")); + xVelo = 10 * direction; + } + + public void move(){ + this.x += xVelo; + this.rect.x = this.x; + } +} \ No newline at end of file diff --git a/Sprite.java b/Sprite.java new file mode 100644 index 0000000..cfed4ce --- /dev/null +++ b/Sprite.java @@ -0,0 +1,13 @@ +import java.awt.Graphics; +import javax.swing.ImageIcon; +import java.awt.Image; + +public class Sprite{ + ImageIcon icon; + Image sprite; + + public Sprite(ImageIcon i){ + icon = i; + sprite = i.getImage(); + } +} \ No newline at end of file diff --git a/Sprites/Amendment.png b/Sprites/Amendment.png new file mode 100644 index 0000000..e7c2431 --- /dev/null +++ b/Sprites/Amendment.png @@ -0,0 +1 @@ +https://codehs.com/uploads/ae6cafb9fe209cffdb709e04ae3f920c \ No newline at end of file diff --git a/Sprites/Bricks/Brick.png b/Sprites/Bricks/Brick.png new file mode 100644 index 0000000..b938b4a --- /dev/null +++ b/Sprites/Bricks/Brick.png @@ -0,0 +1 @@ +https://codehs.com/uploads/cf4f4ed9f8f3528c4c63f0f1a6295ac4 \ No newline at end of file diff --git a/Sprites/Bricks/EmptyBrick.png b/Sprites/Bricks/EmptyBrick.png new file mode 100644 index 0000000..57778e3 Binary files /dev/null and b/Sprites/Bricks/EmptyBrick.png differ diff --git a/Sprites/Bricks/PowerBrick.png b/Sprites/Bricks/PowerBrick.png new file mode 100644 index 0000000..0723b1f --- /dev/null +++ b/Sprites/Bricks/PowerBrick.png @@ -0,0 +1 @@ +https://codehs.com/uploads/cbad697ce83a7d4a42bbc964204dc705 \ No newline at end of file diff --git a/Sprites/Enemies/1.png b/Sprites/Enemies/1.png new file mode 100644 index 0000000..9b4c812 --- /dev/null +++ b/Sprites/Enemies/1.png @@ -0,0 +1 @@ +https://codehs.com/uploads/305ac06e82fd35bd134f7fa0c931601b \ No newline at end of file diff --git a/Sprites/Enemies/10.png b/Sprites/Enemies/10.png new file mode 100644 index 0000000..5e627d6 Binary files /dev/null and b/Sprites/Enemies/10.png differ diff --git a/Sprites/Enemies/2.png b/Sprites/Enemies/2.png new file mode 100644 index 0000000..51b6415 Binary files /dev/null and b/Sprites/Enemies/2.png differ diff --git a/Sprites/Enemies/3.png b/Sprites/Enemies/3.png new file mode 100644 index 0000000..6f0f11f Binary files /dev/null and b/Sprites/Enemies/3.png differ diff --git a/Sprites/Enemies/4.png b/Sprites/Enemies/4.png new file mode 100644 index 0000000..3701c47 Binary files /dev/null and b/Sprites/Enemies/4.png differ diff --git a/Sprites/Enemies/5.png b/Sprites/Enemies/5.png new file mode 100644 index 0000000..745462c Binary files /dev/null and b/Sprites/Enemies/5.png differ diff --git a/Sprites/Enemies/6.png b/Sprites/Enemies/6.png new file mode 100644 index 0000000..02bc268 Binary files /dev/null and b/Sprites/Enemies/6.png differ diff --git a/Sprites/Enemies/7.png b/Sprites/Enemies/7.png new file mode 100644 index 0000000..6925fe1 Binary files /dev/null and b/Sprites/Enemies/7.png differ diff --git a/Sprites/Enemies/8.png b/Sprites/Enemies/8.png new file mode 100644 index 0000000..cc296c4 Binary files /dev/null and b/Sprites/Enemies/8.png differ diff --git a/Sprites/Enemies/9.png b/Sprites/Enemies/9.png new file mode 100644 index 0000000..d99a513 Binary files /dev/null and b/Sprites/Enemies/9.png differ diff --git a/Sprites/Flag.png b/Sprites/Flag.png new file mode 100644 index 0000000..8820672 --- /dev/null +++ b/Sprites/Flag.png @@ -0,0 +1 @@ +https://codehs.com/uploads/0a1df70bf07192d8e22a035e94c505ee \ No newline at end of file diff --git a/Sprites/Hearts/emptyHeart.png b/Sprites/Hearts/emptyHeart.png new file mode 100644 index 0000000..fc9ea8d --- /dev/null +++ b/Sprites/Hearts/emptyHeart.png @@ -0,0 +1 @@ +https://codehs.com/uploads/d274234279511b1e39ecf21bb57c4089 \ No newline at end of file diff --git a/Sprites/Hearts/heart.png b/Sprites/Hearts/heart.png new file mode 100644 index 0000000..0f419d1 --- /dev/null +++ b/Sprites/Hearts/heart.png @@ -0,0 +1 @@ +https://codehs.com/uploads/e4a51b0d328d57cc754bd30e4e9e63fb \ No newline at end of file diff --git a/Sprites/Numbers/0.png b/Sprites/Numbers/0.png new file mode 100644 index 0000000..468c301 --- /dev/null +++ b/Sprites/Numbers/0.png @@ -0,0 +1 @@ +https://codehs.com/uploads/54fc080d15544d73da00a23a88dc1830 \ No newline at end of file diff --git a/Sprites/Numbers/1.png b/Sprites/Numbers/1.png new file mode 100644 index 0000000..3a3c464 --- /dev/null +++ b/Sprites/Numbers/1.png @@ -0,0 +1 @@ +https://codehs.com/uploads/cdbc9f83021c1a7220a87f6c62a23449 \ No newline at end of file diff --git a/Sprites/Numbers/2.png b/Sprites/Numbers/2.png new file mode 100644 index 0000000..5ccf295 --- /dev/null +++ b/Sprites/Numbers/2.png @@ -0,0 +1 @@ +https://codehs.com/uploads/193ebd763d317d719e7c2b165a139de4 \ No newline at end of file diff --git a/Sprites/Numbers/3.png b/Sprites/Numbers/3.png new file mode 100644 index 0000000..e6cbeba --- /dev/null +++ b/Sprites/Numbers/3.png @@ -0,0 +1 @@ +https://codehs.com/uploads/c83beb8faa706bb5e8e25136bc8324a6 \ No newline at end of file diff --git a/Sprites/Numbers/4.png b/Sprites/Numbers/4.png new file mode 100644 index 0000000..721f414 --- /dev/null +++ b/Sprites/Numbers/4.png @@ -0,0 +1 @@ +https://codehs.com/uploads/6106b192d84b13427fb16465c38db555 \ No newline at end of file diff --git a/Sprites/Numbers/5.png b/Sprites/Numbers/5.png new file mode 100644 index 0000000..620651f --- /dev/null +++ b/Sprites/Numbers/5.png @@ -0,0 +1 @@ +https://codehs.com/uploads/4dad5bd246e0edd132d42cfa38a9644f \ No newline at end of file diff --git a/Sprites/Numbers/6.png b/Sprites/Numbers/6.png new file mode 100644 index 0000000..99a03db --- /dev/null +++ b/Sprites/Numbers/6.png @@ -0,0 +1 @@ +https://codehs.com/uploads/c9e3a54e480756140af1609a340bcc53 \ No newline at end of file diff --git a/Sprites/Numbers/7.png b/Sprites/Numbers/7.png new file mode 100644 index 0000000..397e771 --- /dev/null +++ b/Sprites/Numbers/7.png @@ -0,0 +1 @@ +https://codehs.com/uploads/17e754acd63cc6126805c5729b716a16 \ No newline at end of file diff --git a/Sprites/Numbers/8.png b/Sprites/Numbers/8.png new file mode 100644 index 0000000..26d2d46 --- /dev/null +++ b/Sprites/Numbers/8.png @@ -0,0 +1 @@ +https://codehs.com/uploads/2e95c52737d738addc8cbaa0767c3ae6 \ No newline at end of file diff --git a/Sprites/Numbers/9.png b/Sprites/Numbers/9.png new file mode 100644 index 0000000..b0f437e --- /dev/null +++ b/Sprites/Numbers/9.png @@ -0,0 +1 @@ +https://codehs.com/uploads/35562131a9fb377b61420c7fbae7e6c8 \ No newline at end of file diff --git a/Sprites/Numbers/Slash.png b/Sprites/Numbers/Slash.png new file mode 100644 index 0000000..a44cfd8 --- /dev/null +++ b/Sprites/Numbers/Slash.png @@ -0,0 +1 @@ +https://codehs.com/uploads/22ca4a93f7ca7453cfa84e5bf1da2689 \ No newline at end of file diff --git a/Sprites/Player/1.png b/Sprites/Player/1.png new file mode 100644 index 0000000..716f4fe --- /dev/null +++ b/Sprites/Player/1.png @@ -0,0 +1 @@ +https://codehs.com/uploads/2aa3cacee002d33ea96fa5cb529e912a \ No newline at end of file diff --git a/Sprites/Player/2.png b/Sprites/Player/2.png new file mode 100644 index 0000000..e1c7f24 Binary files /dev/null and b/Sprites/Player/2.png differ diff --git a/Sprites/Player/3.png b/Sprites/Player/3.png new file mode 100644 index 0000000..dedc9c6 Binary files /dev/null and b/Sprites/Player/3.png differ diff --git a/Sprites/Powerup1.png b/Sprites/Powerup1.png new file mode 100644 index 0000000..00457c6 --- /dev/null +++ b/Sprites/Powerup1.png @@ -0,0 +1 @@ +https://codehs.com/uploads/36eb80fcc278bf95db23bf9637b59cf0 \ No newline at end of file diff --git a/Sprites/Projectiles/1.png b/Sprites/Projectiles/1.png new file mode 100644 index 0000000..6503a78 Binary files /dev/null and b/Sprites/Projectiles/1.png differ diff --git a/Sprites/Projectiles/2.png b/Sprites/Projectiles/2.png new file mode 100644 index 0000000..7ac65a3 Binary files /dev/null and b/Sprites/Projectiles/2.png differ diff --git a/Tile.java b/Tile.java new file mode 100644 index 0000000..5bbad59 --- /dev/null +++ b/Tile.java @@ -0,0 +1,11 @@ +import java.awt.Graphics; +import javax.swing.ImageIcon; + +public class Tile extends Collidable { + + public Tile(int x, int y, int w, int h,ImageIcon i){ + super(x,y,w,h,i); + + + } +} \ No newline at end of file