diff --git a/Knuckle's Adventure/.classpath b/Knuckle's Adventure/.classpath new file mode 100644 index 0000000..b8cca6f --- /dev/null +++ b/Knuckle's Adventure/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Knuckle's Adventure/.gitignore b/Knuckle's Adventure/.gitignore new file mode 100644 index 0000000..5e56e04 --- /dev/null +++ b/Knuckle's Adventure/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/Knuckle's Adventure/.project b/Knuckle's Adventure/.project new file mode 100644 index 0000000..de9d52b --- /dev/null +++ b/Knuckle's Adventure/.project @@ -0,0 +1,17 @@ + + + Dragon Tale Tutorial + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/Knuckle's Adventure/.settings/org.eclipse.jdt.core.prefs b/Knuckle's Adventure/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e179d4e --- /dev/null +++ b/Knuckle's Adventure/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Sat Apr 13 11:56:25 EDT 2013 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/Knuckle's Adventure/Libs/jl1.0.1.jar b/Knuckle's Adventure/Libs/jl1.0.1.jar new file mode 100644 index 0000000..bd5fb8b Binary files /dev/null and b/Knuckle's Adventure/Libs/jl1.0.1.jar differ diff --git a/Knuckle's Adventure/Libs/mp3spi1.9.5.jar b/Knuckle's Adventure/Libs/mp3spi1.9.5.jar new file mode 100644 index 0000000..0c74dae Binary files /dev/null and b/Knuckle's Adventure/Libs/mp3spi1.9.5.jar differ diff --git a/Knuckle's Adventure/Libs/tritonus_share.jar b/Knuckle's Adventure/Libs/tritonus_share.jar new file mode 100644 index 0000000..d21ba89 Binary files /dev/null and b/Knuckle's Adventure/Libs/tritonus_share.jar differ diff --git a/Knuckle's Adventure/Resources/Backgrounds/SunSetHill1.gif b/Knuckle's Adventure/Resources/Backgrounds/SunSetHill1.gif new file mode 100644 index 0000000..de357dc Binary files /dev/null and b/Knuckle's Adventure/Resources/Backgrounds/SunSetHill1.gif differ diff --git a/Knuckle's Adventure/Resources/HUD/hud.gif b/Knuckle's Adventure/Resources/HUD/hud.gif new file mode 100644 index 0000000..b50cf19 Binary files /dev/null and b/Knuckle's Adventure/Resources/HUD/hud.gif differ diff --git a/Knuckle's Adventure/Resources/Maps/level1-1.map b/Knuckle's Adventure/Resources/Maps/level1-1.map new file mode 100644 index 0000000..c5648d5 --- /dev/null +++ b/Knuckle's Adventure/Resources/Maps/level1-1.map @@ -0,0 +1,10 @@ +107 +8 +22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 +22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 19 17 17 17 17 17 17 17 17 17 18 22 22 22 22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 22 22 22 22 22 19 17 17 17 17 17 17 17 18 22 +22 4 0 0 0 0 0 0 0 0 0 0 13 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 0 0 0 0 17 17 17 18 22 22 22 22 22 22 22 22 22 22 22 4 0 0 16 0 0 0 0 0 0 0 17 18 22 22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 22 22 22 22 4 0 0 0 0 0 0 0 3 22 +22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 23 24 25 0 0 0 0 0 0 0 17 17 18 22 22 22 22 22 22 22 19 0 0 10 0 11 0 0 0 0 0 0 0 0 17 17 0 0 0 0 9 0 0 0 0 1 21 2 0 0 0 0 0 0 18 22 22 22 4 0 0 0 0 0 0 0 3 22 +22 4 0 0 0 12 0 0 0 0 0 0 11 1 21 21 2 0 0 0 0 0 0 0 0 0 0 15 0 0 0 0 0 23 25 0 0 0 0 0 0 0 0 0 0 9 11 0 0 0 0 0 17 17 17 17 17 17 17 0 0 1 21 21 21 2 0 0 0 0 0 0 0 0 0 0 0 0 0 23 24 25 0 0 3 22 4 0 0 0 0 0 0 0 18 22 22 4 0 0 0 0 0 0 0 3 22 +22 4 0 0 0 0 0 0 0 0 1 21 21 21 6 22 4 0 0 0 0 0 10 9 0 0 0 0 0 0 10 0 0 0 0 0 0 11 0 0 0 0 0 1 21 21 21 21 2 0 0 0 9 0 0 0 0 9 0 0 0 3 22 22 22 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 22 4 0 0 0 0 0 0 0 0 17 17 0 0 0 0 0 0 0 0 3 22 +22 4 9 0 10 0 0 0 0 11 3 22 22 22 22 22 4 0 0 0 1 21 21 21 21 2 0 0 9 1 21 21 2 0 9 1 21 21 2 0 0 0 0 3 22 22 22 22 4 10 0 1 21 2 0 0 1 21 2 11 1 21 6 22 22 4 0 0 0 0 0 0 0 9 0 0 10 9 0 0 11 0 0 1 21 5 21 2 0 0 0 0 0 0 0 0 0 0 0 10 11 0 0 9 0 3 22 +5 21 21 21 21 21 21 21 21 21 21 6 22 22 22 22 4 0 0 0 3 22 22 22 22 21 21 21 21 21 6 5 21 21 21 21 6 22 4 0 0 0 0 3 22 22 22 5 21 21 21 21 21 21 21 21 21 21 21 21 21 6 22 22 22 4 0 0 0 0 0 1 21 21 21 21 21 21 21 21 21 21 21 21 6 22 5 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 6 diff --git a/Knuckle's Adventure/Resources/Menu/Emblem.gif b/Knuckle's Adventure/Resources/Menu/Emblem.gif new file mode 100644 index 0000000..9668946 Binary files /dev/null and b/Knuckle's Adventure/Resources/Menu/Emblem.gif differ diff --git a/Knuckle's Adventure/Resources/Menu/Emblem2.gif b/Knuckle's Adventure/Resources/Menu/Emblem2.gif new file mode 100644 index 0000000..0afbb32 Binary files /dev/null and b/Knuckle's Adventure/Resources/Menu/Emblem2.gif differ diff --git a/Knuckle's Adventure/Resources/Menu/Island_Background.gif b/Knuckle's Adventure/Resources/Menu/Island_Background.gif new file mode 100644 index 0000000..9d20fab Binary files /dev/null and b/Knuckle's Adventure/Resources/Menu/Island_Background.gif differ diff --git a/Knuckle's Adventure/Resources/Menu/Island_Background2.gif b/Knuckle's Adventure/Resources/Menu/Island_Background2.gif new file mode 100644 index 0000000..70151a7 Binary files /dev/null and b/Knuckle's Adventure/Resources/Menu/Island_Background2.gif differ diff --git a/Knuckle's Adventure/Resources/Music/EmeraldHillZone.mp3 b/Knuckle's Adventure/Resources/Music/EmeraldHillZone.mp3 new file mode 100644 index 0000000..8a72963 Binary files /dev/null and b/Knuckle's Adventure/Resources/Music/EmeraldHillZone.mp3 differ diff --git a/Knuckle's Adventure/Resources/Music/IceCapZone.mp3 b/Knuckle's Adventure/Resources/Music/IceCapZone.mp3 new file mode 100644 index 0000000..7171ae1 Binary files /dev/null and b/Knuckle's Adventure/Resources/Music/IceCapZone.mp3 differ diff --git a/Knuckle's Adventure/Resources/Music/Intro.mp3 b/Knuckle's Adventure/Resources/Music/Intro.mp3 new file mode 100644 index 0000000..ea3f477 Binary files /dev/null and b/Knuckle's Adventure/Resources/Music/Intro.mp3 differ diff --git a/Knuckle's Adventure/Resources/Music/Sonic The Hedgehog 2 HD intro alternate version.mp3 b/Knuckle's Adventure/Resources/Music/Sonic The Hedgehog 2 HD intro alternate version.mp3 new file mode 100644 index 0000000..f3e5f5a Binary files /dev/null and b/Knuckle's Adventure/Resources/Music/Sonic The Hedgehog 2 HD intro alternate version.mp3 differ diff --git a/Knuckle's Adventure/Resources/Music/Tee.mp3 b/Knuckle's Adventure/Resources/Music/Tee.mp3 new file mode 100644 index 0000000..8a72963 Binary files /dev/null and b/Knuckle's Adventure/Resources/Music/Tee.mp3 differ diff --git a/Knuckle's Adventure/Resources/SFX/jump.mp3 b/Knuckle's Adventure/Resources/SFX/jump.mp3 new file mode 100644 index 0000000..46c3fe0 Binary files /dev/null and b/Knuckle's Adventure/Resources/SFX/jump.mp3 differ diff --git a/Knuckle's Adventure/Resources/SFX/punch.mp3 b/Knuckle's Adventure/Resources/SFX/punch.mp3 new file mode 100644 index 0000000..edfdadb Binary files /dev/null and b/Knuckle's Adventure/Resources/SFX/punch.mp3 differ diff --git a/Knuckle's Adventure/Resources/Sprites/Enemies/Motobug-sprite.gif b/Knuckle's Adventure/Resources/Sprites/Enemies/Motobug-sprite.gif new file mode 100644 index 0000000..5c8a73c Binary files /dev/null and b/Knuckle's Adventure/Resources/Sprites/Enemies/Motobug-sprite.gif differ diff --git a/Knuckle's Adventure/Resources/Sprites/Enemies/moto.gif b/Knuckle's Adventure/Resources/Sprites/Enemies/moto.gif new file mode 100644 index 0000000..dd0d9ad Binary files /dev/null and b/Knuckle's Adventure/Resources/Sprites/Enemies/moto.gif differ diff --git a/Knuckle's Adventure/Resources/Sprites/Player/fireball.gif b/Knuckle's Adventure/Resources/Sprites/Player/fireball.gif new file mode 100644 index 0000000..b490d13 Binary files /dev/null and b/Knuckle's Adventure/Resources/Sprites/Player/fireball.gif differ diff --git a/Knuckle's Adventure/Resources/Sprites/Player/knucks.gif b/Knuckle's Adventure/Resources/Sprites/Player/knucks.gif new file mode 100644 index 0000000..2df54df Binary files /dev/null and b/Knuckle's Adventure/Resources/Sprites/Player/knucks.gif differ diff --git a/Knuckle's Adventure/Resources/Sprites/Player/rings ss.gif b/Knuckle's Adventure/Resources/Sprites/Player/rings ss.gif new file mode 100644 index 0000000..b4fd65d Binary files /dev/null and b/Knuckle's Adventure/Resources/Sprites/Player/rings ss.gif differ diff --git a/Knuckle's Adventure/Resources/Tilesets/Thumbs.db b/Knuckle's Adventure/Resources/Tilesets/Thumbs.db new file mode 100644 index 0000000..508ec66 Binary files /dev/null and b/Knuckle's Adventure/Resources/Tilesets/Thumbs.db differ diff --git a/Knuckle's Adventure/Resources/Tilesets/TileSet.gif b/Knuckle's Adventure/Resources/Tilesets/TileSet.gif new file mode 100644 index 0000000..fc2ef33 Binary files /dev/null and b/Knuckle's Adventure/Resources/Tilesets/TileSet.gif differ diff --git a/Knuckle's Adventure/Resources/Tilesets/grasstileset.gif b/Knuckle's Adventure/Resources/Tilesets/grasstileset.gif new file mode 100644 index 0000000..f53b848 Binary files /dev/null and b/Knuckle's Adventure/Resources/Tilesets/grasstileset.gif differ diff --git a/Knuckle's Adventure/src/Audio/AudioPlayer.java b/Knuckle's Adventure/src/Audio/AudioPlayer.java new file mode 100644 index 0000000..a01f93f --- /dev/null +++ b/Knuckle's Adventure/src/Audio/AudioPlayer.java @@ -0,0 +1,71 @@ +package Audio; + +import javax.sound.sampled.*; + +public class AudioPlayer { + + private Clip clip; + + public AudioPlayer(String s) { + + try { + + AudioInputStream ais = + AudioSystem.getAudioInputStream( + getClass().getResourceAsStream( + s + ) + ); + AudioFormat baseFormat = ais.getFormat(); + AudioFormat decodeFormat = new AudioFormat( + AudioFormat.Encoding.PCM_SIGNED, + baseFormat.getSampleRate(), + 16, + baseFormat.getChannels(), + baseFormat.getChannels() * 2, + baseFormat.getSampleRate(), + false + ); + AudioInputStream dais = + AudioSystem.getAudioInputStream( + decodeFormat, ais); + clip = AudioSystem.getClip(); + clip.open(dais); + } + catch(Exception e) { + e.printStackTrace(); + } + + } + + public void play() { + if(clip == null) return; + stop(); + clip.setFramePosition(0); + clip.start(); + } + + public void stop() { + if(clip.isRunning()) clip.stop(); + } + + public void close() { + stop(); + clip.close(); + } + +} + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/Animation.java b/Knuckle's Adventure/src/Entity/Animation.java new file mode 100644 index 0000000..32ef387 --- /dev/null +++ b/Knuckle's Adventure/src/Entity/Animation.java @@ -0,0 +1,65 @@ +package Entity; + +import java.awt.image.BufferedImage; + +public class Animation { + + private BufferedImage[] frames; + private int currentFrame; + + private long startTime; + private long delay; + + private boolean playedOnce; + + public Animation() { + playedOnce = false; + } + + public void setFrames(BufferedImage[] frames) { + this.frames = frames; + currentFrame = 0; + startTime = System.nanoTime(); + playedOnce = false; + } + + public void setDelay(long d) { delay = d; } + public void setFrame(int i) { currentFrame = i; } + + public void update() { + + if(delay == -1) return; + + long elapsed = (System.nanoTime() - startTime) / 1000000; + if(elapsed > delay) { + currentFrame++; + startTime = System.nanoTime(); + } + if(currentFrame == frames.length) { + currentFrame = 0; + playedOnce = true; + } + + } + + public int getFrame() { return currentFrame; } + public BufferedImage getImage() { return frames[currentFrame]; } + public boolean hasPlayedOnce() { return playedOnce; } + +} + + + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/Blast.java b/Knuckle's Adventure/src/Entity/Blast.java new file mode 100644 index 0000000..4464551 --- /dev/null +++ b/Knuckle's Adventure/src/Entity/Blast.java @@ -0,0 +1,123 @@ +package Entity; + +import TileMap.TileMap; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +public class Blast extends MapObject { + + private boolean hit; + private boolean remove; + private BufferedImage[] sprites; + private BufferedImage[] hitSprites; + + public Blast(TileMap tm, boolean right) { + + super(tm); + + facingRight = right; + + moveSpeed = 3.8; + if(right) dx = moveSpeed; + else dx = -moveSpeed; + + width = 16; + height = 16; + cwidth = 14; + cheight = 14; + + // load sprites + try { + + BufferedImage spritesheet = ImageIO.read( + getClass().getResourceAsStream( + "/Sprites/Player/rings ss.gif" + ) + ); + + sprites = new BufferedImage[8]; + for(int i = 0; i < sprites.length; i++) { + sprites[i] = spritesheet.getSubimage( + i * width, + 0, + width, + height + ); + } + + hitSprites = new BufferedImage[7]; + for(int i = 0; i < hitSprites.length; i++) { + hitSprites[i] = spritesheet.getSubimage( + i * width, + height, + width, + height + ); + } + + animation = new Animation(); + animation.setFrames(sprites); + animation.setDelay(70); + + } + catch(Exception e) { + e.printStackTrace(); + } + + } + + public void setHit() { + if(hit) return; + hit = true; + animation.setFrames(hitSprites); + animation.setDelay(70); + dx = 0; + } + + public boolean shouldRemove() { return remove; } + + public void update() { + + checkTileMapCollision(); + setPosition(xtemp, ytemp); + + if(dx == 0 && !hit) { + setHit(); + } + + animation.update(); + if(hit && animation.hasPlayedOnce()) { + remove = true; + } + + } + + public void draw(Graphics2D g) { + + setMapPosition(); + + super.draw(g); + + } + +} + + + + + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/Enemies/Motobug.java b/Knuckle's Adventure/src/Entity/Enemies/Motobug.java new file mode 100644 index 0000000..35ce67e --- /dev/null +++ b/Knuckle's Adventure/src/Entity/Enemies/Motobug.java @@ -0,0 +1,142 @@ +package Entity.Enemies; + +import Entity.*; +import TileMap.TileMap; + +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; + +import javax.imageio.ImageIO; + +public class Motobug extends Enemy { + + private BufferedImage[] sprites; + + public Motobug(TileMap tm) { + + super(tm); + + moveSpeed = 0.3; + maxSpeed = 0.3; + fallSpeed = 0.2; + maxFallSpeed = 10.0; + + width = 48; + height = 48; + cwidth = 45; + cheight = 45; + + health = maxHealth = 2; + damage = 1; + + // load sprites + try { + + BufferedImage spritesheet = ImageIO.read( + getClass().getResourceAsStream( + "/Sprites/Enemies/moto.gif" + ) + ); + + sprites = new BufferedImage[3]; + for(int i = 0; i < sprites.length; i++) { + sprites[i] = spritesheet.getSubimage( + i * width, + 0, + width, + height + ); + } + + } + catch(Exception e) { + e.printStackTrace(); + } + + animation = new Animation(); + animation.setFrames(sprites); + animation.setDelay(300); + + right = true; + facingRight = true; + + } + + private void getNextPosition() { + + // movement + if(left) { + dx -= moveSpeed; + if(dx < -maxSpeed) { + dx = -maxSpeed; + } + } + else if(right) { + dx += moveSpeed; + if(dx > maxSpeed) { + dx = maxSpeed; + } + } + + // falling + if(falling) { + dy += fallSpeed; + } + + } + + public void update() { + + // update position + getNextPosition(); + checkTileMapCollision(); + setPosition(xtemp, ytemp); + + // check flinching + if(flinching) { + long elapsed = + (System.nanoTime() - flinchTimer) / 1000000; + if(elapsed > 400) { + flinching = false; + } + } + + // if it hits a wall, go other direction + if(right && dx == 0) { + right = false; + left = true; + facingRight = false; + } + else if(left && dx == 0) { + right = true; + left = false; + facingRight = true; + } + + // update animation + animation.update(); + + } + + public void draw(Graphics2D g) { + + //if(notOnScreen()) return; + + setMapPosition(); + + super.draw(g); + + } + +} + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/Enemy.java b/Knuckle's Adventure/src/Entity/Enemy.java new file mode 100644 index 0000000..fce4459 --- /dev/null +++ b/Knuckle's Adventure/src/Entity/Enemy.java @@ -0,0 +1,48 @@ +package Entity; + +import TileMap.TileMap; + +public class Enemy extends MapObject { + + protected int health; + protected int maxHealth; + protected boolean dead; + protected int damage; + + protected boolean flinching; + protected long flinchTimer; + + public Enemy(TileMap tm) { + super(tm); + } + + public boolean isDead() { return dead; } + + public int getDamage() { return damage; } + + public void hit(int damage) { + if(dead || flinching) return; + health -= damage; + if(health < 0) health = 0; + if(health == 0) dead = true; + flinching = true; + flinchTimer = System.nanoTime(); + } + + public void update() {} + +} + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/Explosion.java b/Knuckle's Adventure/src/Entity/Explosion.java new file mode 100644 index 0000000..97dcb47 --- /dev/null +++ b/Knuckle's Adventure/src/Entity/Explosion.java @@ -0,0 +1,99 @@ +package Entity; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +public class Explosion { + + private int x; + private int y; + private int xmap; + private int ymap; + + private int width; + private int height; + + private Animation animation; + private BufferedImage[] sprites; + + private boolean remove; + + public Explosion(int x, int y) { + + this.x = x; + this.y = y; + + width = 30; + height = 30; + + try { + + BufferedImage spritesheet = ImageIO.read( + getClass().getResourceAsStream( + "/Sprites/Enemies/explosion.gif" + ) + ); + + sprites = new BufferedImage[6]; + for(int i = 0; i < sprites.length; i++) { + sprites[i] = spritesheet.getSubimage( + i * width, + 0, + width, + height + ); + } + + } + catch(Exception e) { + e.printStackTrace(); + } + + animation = new Animation(); + animation.setFrames(sprites); + animation.setDelay(70); + + } + + public void update() { + animation.update(); + if(animation.hasPlayedOnce()) { + remove = true; + } + } + + public boolean shouldRemove() { return remove; } + + public void setMapPosition(int x, int y) { + xmap = x; + ymap = y; + } + + public void draw(Graphics2D g) { + g.drawImage( + animation.getImage(), + x + xmap - width / 2, + y + ymap - height / 2, + null + ); + } + +} + + + + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/HUD.java b/Knuckle's Adventure/src/Entity/HUD.java new file mode 100644 index 0000000..5d144ea --- /dev/null +++ b/Knuckle's Adventure/src/Entity/HUD.java @@ -0,0 +1,58 @@ +package Entity; + +import java.awt.*; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +public class HUD { + + private Knuckles knuckles; + + private BufferedImage image; + private Font font; + + public HUD(Knuckles p) { + knuckles = p; + try { + image = ImageIO.read( + getClass().getResourceAsStream( + "/HUD/hud.gif" + ) + ); + font = new Font("Arial", Font.PLAIN, 14); + } + catch(Exception e) { + e.printStackTrace(); + } + } + public void update() { + + } + + public void draw(Graphics2D g) { + + g.drawImage(image, 0, 10, null); + g.setFont(font); + g.setColor(Color.WHITE); + g.drawString( + knuckles.getHealth() + "/" + knuckles.getMaxHealth(), + 55, + 45 + ); + + } + +} + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/Knuckles.java b/Knuckle's Adventure/src/Entity/Knuckles.java new file mode 100644 index 0000000..d0b6aa0 --- /dev/null +++ b/Knuckle's Adventure/src/Entity/Knuckles.java @@ -0,0 +1,431 @@ +package Entity; + +import TileMap.*; +import Audio.AudioPlayer; + +import java.util.ArrayList; +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.HashMap; + +public class Knuckles extends MapObject { + + // player stuff + private int health; + private int maxHealth; + private int fire; + private int maxFire; + private boolean dead; + private boolean flinching; + private long flinchTimer; + + // blast + private boolean firing; + private int fireCost; + private int fireBallDamage; + private ArrayList blasts; + + // punch + private boolean punching; + private int punchDamage; + private int punchRange; + + // gliding + private boolean gliding; + + // animations + private ArrayList sprites; + private final int[] numFrames = { + 7, 8, 1, 3, 1, 2, + }; + + // animation actions + private static final int IDLE = 0; + private static final int WALKING = 1; + private static final int JUMPING = 2; + private static final int FALLING = 3; + private static final int GLIDING = 4; + private static final int BLAST = 5; + private static final int PUNCHING = 6; + + private HashMap sfx; + + public Knuckles(TileMap tm) { + + super(tm); + + width = 96; + height = 96; + cwidth = 80; + cheight = 80; + + moveSpeed = 4.0; + maxSpeed = 7.6; + stopSpeed = 0.4; + fallSpeed = .15; + maxFallSpeed = 6.0; + jumpStart = -7.8; + stopJumpSpeed = 0.3; + + facingRight = true; + + health = maxHealth = 5; + fire = maxFire = 2500; + + fireCost = 200; + fireBallDamage = 5; + blasts = new ArrayList(); + + punchDamage = 8; + punchRange = 40; + + // load sprites + try { + + BufferedImage spritesheet = ImageIO.read( + getClass().getResourceAsStream( + "/Sprites/Player/knucks.gif" + ) + ); + + sprites = new ArrayList(); + for(int i = 0; i < 9; i++) { + + BufferedImage[] bi = + new BufferedImage[numFrames[i]]; + + for(int j = 0; j < numFrames[i]; j++) { + + if(i != PUNCHING) { + bi[j] = spritesheet.getSubimage( + j * width, + i * height, + width, + height + ); + } + else { + bi[j] = spritesheet.getSubimage( + j * width * 2, + i * height, + width * 2, + height + ); + } + + } + + sprites.add(bi); + + } + + } + catch(Exception e) { + e.printStackTrace(); + } + + animation = new Animation(); + currentAction = IDLE; + animation.setFrames(sprites.get(IDLE)); + animation.setDelay(400); + + sfx = new HashMap(); + sfx.put("jump", new AudioPlayer("/SFX/jump.mp3")); + sfx.put("scratch", new AudioPlayer("/SFX/punch.mp3")); + + } + + public int getHealth() { return health; } + public int getMaxHealth() { return maxHealth; } + public int getFire() { return fire; } + public int getMaxFire() { return maxFire; } + + public void setFiring() { + firing = true; + } + public void setScratching() { + punching = true; + } + public void setGliding(boolean b) { + gliding = b; + } + + public void checkAttack(ArrayList enemies) { + + // loop through enemies + for(int i = 0; i < enemies.size(); i++) { + + Enemy e = enemies.get(i); + + // scratch attack + if(punching) { + if(facingRight) { + if( + e.getx() > x && + e.getx() < x + punchRange && + e.gety() > y - height / 2 && + e.gety() < y + height / 2 + ) { + e.hit(punchDamage); + } + } + else { + if( + e.getx() < x && + e.getx() > x - punchRange && + e.gety() > y - height / 2 && + e.gety() < y + height / 2 + ) { + e.hit(punchDamage); + } + } + } + + // blasts + for(int j = 0; j < blasts.size(); j++) { + if(blasts.get(j).intersects(e)) { + e.hit(fireBallDamage); + blasts.get(j).setHit(); + break; + } + } + + // check enemy collision + if(intersects(e)) { + hit(e.getDamage()); + } + + } + + } + + public void hit(int damage) { + if(flinching) return; + health -= damage; + if(health < 0) health = 0; + if(health == 0) dead = true; + flinching = true; + flinchTimer = System.nanoTime(); + } + + private void getNextPosition() { + + // movement + if(left) { + dx -= moveSpeed; + if(dx < -maxSpeed) { + dx = -maxSpeed; + } + } + else if(right) { + dx += moveSpeed; + if(dx > maxSpeed) { + dx = maxSpeed; + } + } + else { + if(dx > 0) { + dx -= stopSpeed; + if(dx < 0) { + dx = 0; + } + } + else if(dx < 0) { + dx += stopSpeed; + if(dx > 0) { + dx = 0; + } + } + } + + // cannot move while attacking, except in air + if( + (currentAction == PUNCHING || currentAction == BLAST) && + !(jumping || falling)) { + dx = 0; + } + + // jumping + if(jumping && !falling) { + sfx.get("jump").play(); + dy = jumpStart; + falling = true; + } + + // falling + if(falling) { + + if(dy > 0 && gliding) dy += fallSpeed * 0.1; + else dy += fallSpeed; + + if(dy > 0) jumping = false; + if(dy < 0 && !jumping) dy += stopJumpSpeed; + + if(dy > maxFallSpeed) dy = maxFallSpeed; + + } + + } + + public boolean isDead(){ + if (this.getHealth() == 0){ + return true; + } + return false; + } + + public void update() { + + // update position + getNextPosition(); + checkTileMapCollision(); + setPosition(xtemp, ytemp); + + // check attack has stopped + if(currentAction == PUNCHING) { + if(animation.hasPlayedOnce()) punching = false; + } + if(currentAction == BLAST) { + if(animation.hasPlayedOnce()) firing = false; + } + + // blast attack + fire += 1; + if(fire > maxFire) fire = maxFire; + if(firing && currentAction != BLAST) { + if(fire > fireCost) { + fire -= fireCost; + Blast fb = new Blast(tileMap, facingRight); + fb.setPosition(x, y); + blasts.add(fb); + } + } + + // update blasts + for(int i = 0; i < blasts.size(); i++) { + blasts.get(i).update(); + if(blasts.get(i).shouldRemove()) { + blasts.remove(i); + i--; + } + } + + // check done flinching + if(flinching) { + long elapsed = + (System.nanoTime() - flinchTimer) / 1000000; + if(elapsed > 1000) { + flinching = false; + } + } + + // set animation + if(punching) { + if(currentAction != PUNCHING) { + sfx.get("scratch").play(); + currentAction = PUNCHING; + animation.setFrames(sprites.get(PUNCHING)); + animation.setDelay(50); + width = 60; + } + } + else if(firing) { + if(currentAction != BLAST) { + currentAction = BLAST; + animation.setFrames(sprites.get(BLAST)); + animation.setDelay(100); + width = 30; + } + } + else if(dy > 0) { + if(gliding) { + if(currentAction != GLIDING) { + currentAction = GLIDING; + animation.setFrames(sprites.get(GLIDING)); + animation.setDelay(100); + width = 30; + } + } + else if(currentAction != FALLING) { + currentAction = FALLING; + animation.setFrames(sprites.get(FALLING)); + animation.setDelay(100); + width = 30; + } + } + else if(dy < 0) { + if(currentAction != JUMPING) { + currentAction = JUMPING; + animation.setFrames(sprites.get(JUMPING)); + animation.setDelay(-1); + width = 30; + } + } + else if(left || right) { + if(currentAction != WALKING) { + currentAction = WALKING; + animation.setFrames(sprites.get(WALKING)); + animation.setDelay(40); + width = 30; + } + } + else { + if(currentAction != IDLE) { + currentAction = IDLE; + animation.setFrames(sprites.get(IDLE)); + animation.setDelay(400); + width = 30; + } + } + + animation.update(); + + // set direction + if(currentAction != PUNCHING && currentAction != BLAST) { + if(right) facingRight = true; + if(left) facingRight = false; + } + + } + + public void draw(Graphics2D g) { + + setMapPosition(); + + // draw blasts + for(int i = 0; i < blasts.size(); i++) { + blasts.get(i).draw(g); + } + + // draw player + if(flinching) { + long elapsed = + (System.nanoTime() - flinchTimer) / 1000000; + if(elapsed / 100 % 2 == 0) { + return; + } + } + + super.draw(g); + + } + +} + + + + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Entity/MapObject.java b/Knuckle's Adventure/src/Entity/MapObject.java new file mode 100644 index 0000000..da36f07 --- /dev/null +++ b/Knuckle's Adventure/src/Entity/MapObject.java @@ -0,0 +1,238 @@ +package Entity; + +import Main.GamePanel; +import TileMap.TileMap; +import TileMap.Tile; + +import java.awt.Rectangle; + +public abstract class MapObject { + + // tile stuff + protected TileMap tileMap; + protected int tileSize; + protected double xmap; + protected double ymap; + + // position and vector + protected double x; + protected double y; + protected double dx; + protected double dy; + + // dimensions + protected int width; + protected int height; + + // collision box + protected int cwidth; + protected int cheight; + + // collision + protected int currRow; + protected int currCol; + protected double xdest; + protected double ydest; + protected double xtemp; + protected double ytemp; + protected boolean topLeft; + protected boolean topRight; + protected boolean bottomLeft; + protected boolean bottomRight; + + // animation + protected Animation animation; + protected int currentAction; + protected int previousAction; + protected boolean facingRight; + + // movement + protected boolean left; + protected boolean right; + protected boolean up; + protected boolean down; + protected boolean jumping; + protected boolean falling; + + // movement attributes + protected double moveSpeed; + protected double maxSpeed; + protected double stopSpeed; + protected double fallSpeed; + protected double maxFallSpeed; + protected double jumpStart; + protected double stopJumpSpeed; + + // constructor + public MapObject(TileMap tm) { + tileMap = tm; + tileSize = tm.getTileSize(); + } + + public boolean intersects(MapObject o) { + Rectangle r1 = getRectangle(); + Rectangle r2 = o.getRectangle(); + return r1.intersects(r2); + } + + public Rectangle getRectangle() { + return new Rectangle( + (int)x - cwidth, + (int)y - cheight, + cwidth, + cheight + ); + } + + public void calculateCorners(double x, double y) { + + int leftTile = (int)(x - cwidth / 2) / tileSize; + int rightTile = (int)(x + cwidth / 2 - 1) / tileSize; + int topTile = (int)(y - cheight / 2) / tileSize; + int bottomTile = (int)(y + cheight / 2 - 1) / tileSize; + + int tl = tileMap.getType(topTile, leftTile); + int tr = tileMap.getType(topTile, rightTile); + int bl = tileMap.getType(bottomTile, leftTile); + int br = tileMap.getType(bottomTile, rightTile); + + topLeft = tl == Tile.BLOCKED; + topRight = tr == Tile.BLOCKED; + bottomLeft = bl == Tile.BLOCKED; + bottomRight = br == Tile.BLOCKED; + + } + + public void checkTileMapCollision() { + + currCol = (int)x / tileSize; + currRow = (int)y / tileSize; + + xdest = x + dx; + ydest = y + dy; + + xtemp = x; + ytemp = y; + + calculateCorners(x, ydest); + if(dy < 0) { + if(topLeft || topRight) { + dy = 0; + ytemp = currRow * tileSize + cheight / 2; + } + else { + ytemp += dy; + } + } + if(dy > 0) { + if(bottomLeft || bottomRight) { + dy = 0; + falling = false; + ytemp = (currRow + 1) * tileSize - cheight / 2; + } + else { + ytemp += dy; + } + } + + calculateCorners(xdest, y); + if(dx < 0) { + if(topLeft || bottomLeft) { + dx = 0; + xtemp = currCol * tileSize + cwidth / 2; + } + else { + xtemp += dx; + } + } + if(dx > 0) { + if(topRight || bottomRight) { + dx = 0; + xtemp = (currCol + 1) * tileSize - cwidth / 2; + } + else { + xtemp += dx; + } + } + + if(!falling) { + calculateCorners(x, ydest + 1); + if(!bottomLeft && !bottomRight) { + falling = true; + } + } + + } + + public int getx() { return (int)x; } + public int gety() { return (int)y; } + public int getWidth() { return width; } + public int getHeight() { return height; } + public int getCWidth() { return cwidth; } + public int getCHeight() { return cheight; } + + public void setPosition(double x, double y) { + this.x = x; + this.y = y; + } + public void setVector(double dx, double dy) { + this.dx = dx; + this.dy = dy; + } + + public void setMapPosition() { + xmap = tileMap.getx(); + ymap = tileMap.gety(); + } + + public void setLeft(boolean b) { left = b; } + public void setRight(boolean b) { right = b; } + public void setUp(boolean b) { up = b; } + public void setDown(boolean b) { down = b; } + public void setJumping(boolean b) { jumping = b; } + + public boolean notOnScreen() { + return x + xmap + width < 0 || + x + xmap - width > GamePanel.WIDTH || + y + ymap + height < 0 || + y + ymap - height > GamePanel.HEIGHT; + } + + public void draw(java.awt.Graphics2D g) { + if(facingRight) { + g.drawImage( + animation.getImage(), + (int)(x + xmap - width / 2), + (int)(y + ymap - height / 2), + null + ); + } + else { + g.drawImage( + animation.getImage(), + (int)(x + xmap - width / 2 + 2*width), + (int)(y + ymap - height / 2), + -3*width, + height, + null + ); + } + } + +} + + + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/GameState/GameState.java b/Knuckle's Adventure/src/GameState/GameState.java new file mode 100644 index 0000000..5af1653 --- /dev/null +++ b/Knuckle's Adventure/src/GameState/GameState.java @@ -0,0 +1,13 @@ +package GameState; + +public abstract class GameState { + + protected GameStateManager gsm; + + public abstract void init(); + public abstract void update(); + public abstract void draw(java.awt.Graphics2D g); + public abstract void keyPressed(int k); + public abstract void keyReleased(int k); + +} diff --git a/Knuckle's Adventure/src/GameState/GameStateManager.java b/Knuckle's Adventure/src/GameState/GameStateManager.java new file mode 100644 index 0000000..80b2a9a --- /dev/null +++ b/Knuckle's Adventure/src/GameState/GameStateManager.java @@ -0,0 +1,70 @@ +package GameState; + +import java.util.ArrayList; + +public class GameStateManager { + + private GameState[] gameStates; + private int currentState; + + public static final int NUMGAMESTATES = 2; + public static final int MENUSTATE = 0; + public static final int LEVEL1STATE = 1; + + public GameStateManager() { + + gameStates = new GameState[NUMGAMESTATES]; + + currentState = MENUSTATE; + loadState(currentState); + + } + + void loadState(int state) { + if(state == MENUSTATE) + gameStates[state] = new MenuState(this); + if(state == LEVEL1STATE) + gameStates[state] = new Level1State(this); + } + + private void unloadState(int state) { + gameStates[state] = null; + } + + public void setState(int state) { + unloadState(currentState); + currentState = state; + loadState(currentState); + //gameStates[currentState].init(); + } + + public void update() { + try { + gameStates[currentState].update(); + } catch(Exception e) {} + } + + public void draw(java.awt.Graphics2D g) { + try { + gameStates[currentState].draw(g); + } catch(Exception e) {} + } + + public void keyPressed(int k) { + gameStates[currentState].keyPressed(k); + } + + public void keyReleased(int k) { + gameStates[currentState].keyReleased(k); + } + +} + + + + + + + + + diff --git a/Knuckle's Adventure/src/GameState/Level1State.java b/Knuckle's Adventure/src/GameState/Level1State.java new file mode 100644 index 0000000..5a1a2b1 --- /dev/null +++ b/Knuckle's Adventure/src/GameState/Level1State.java @@ -0,0 +1,182 @@ +package GameState; + +import Main.GamePanel; +import TileMap.*; +import Entity.*; +import Entity.Enemies.*; +import Audio.AudioPlayer; +import Main.Game; + +import javax.swing.JFrame; + +import com.sun.java.swing.plaf.windows.resources.windows; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.util.ArrayList; + + + +public class Level1State extends GameState { + + private TileMap tileMap; + private Background bg; + + private Knuckles knuckles; + + private ArrayList enemies; + private ArrayList explosions; + + private HUD hud; + + private AudioPlayer bgMusic; + + public Level1State(GameStateManager gsm) { + this.gsm = gsm; + init(); + } + + public void init() { + + tileMap = new TileMap(96); + tileMap.loadTiles("/Tilesets/TileSet.gif"); + tileMap.loadMap("/Maps/level1-1.map"); + tileMap.setPosition(0, 0); + tileMap.setTween(1); + + bg = new Background("/Backgrounds/SunSetHill1.gif", 0.0); + + knuckles = new Knuckles(tileMap); + knuckles.setPosition(140, 300); + + populateEnemies(); + + explosions = new ArrayList(); + + hud = new HUD(knuckles); + + bgMusic = new AudioPlayer("/Music/Tee.mp3"); + bgMusic.play(); + + } + + private void populateEnemies() { + + enemies = new ArrayList(); + + Motobug m; + Point[] points = new Point[] { + new Point(200, 100), + new Point(860, 200), + new Point(2496, 200), + new Point(3168, 200), + new Point(3744, 200), + new Point(4608, 350) + }; + for(int i = 0; i < points.length; i++) { + m = new Motobug(tileMap); + m.setPosition(points[i].x, points[i].y); + enemies.add(m); + } + + } + + public void update() { + + // update player + knuckles.update(); + tileMap.setPosition( + GamePanel.WIDTH / 2 - knuckles.getx(), + GamePanel.HEIGHT / 2 - knuckles.gety() + ); + + // set background + bg.setPosition(tileMap.getx(), tileMap.gety()); + + // attack enemies + knuckles.checkAttack(enemies); + + // update all enemies + for(int i = 0; i < enemies.size(); i++) { + Enemy e = enemies.get(i); + e.update(); + if(e.isDead()) { + enemies.remove(i); + i--; + explosions.add( + new Explosion(e.getx(), e.gety())); + } + } + + // update explosions + for(int i = 0; i < explosions.size(); i++) { + explosions.get(i).update(); + if(explosions.get(i).shouldRemove()) { + explosions.remove(i); + i--; + } + } + + } + + public void draw(Graphics2D g) { + + // draw bg + bg.draw(g); + + // draw tilemap + tileMap.draw(g); + + // draw player + knuckles.draw(g); + + // draw enemies + for(int i = 0; i < enemies.size(); i++) { + enemies.get(i).draw(g); + } + + // draw explosions + for(int i = 0; i < explosions.size(); i++) { + explosions.get(i).setMapPosition( + (int)tileMap.getx(), (int)tileMap.gety()); + explosions.get(i).draw(g); + } + + // draw hud + hud.draw(g); + + } + + public void keyPressed(int k) { + if(k == KeyEvent.VK_LEFT) knuckles.setLeft(true); + if(k == KeyEvent.VK_RIGHT) knuckles.setRight(true); + if(k == KeyEvent.VK_UP) knuckles.setUp(true); + if(k == KeyEvent.VK_DOWN) knuckles.setDown(true); + if(k == KeyEvent.VK_W) knuckles.setJumping(true); + if(k == KeyEvent.VK_E) knuckles.setGliding(true); + if(k == KeyEvent.VK_R) knuckles.setScratching(); + if(k == KeyEvent.VK_F) knuckles.setFiring(); + } + + public void keyReleased(int k) { + if(k == KeyEvent.VK_LEFT) knuckles.setLeft(false); + if(k == KeyEvent.VK_RIGHT) knuckles.setRight(false); + if(k == KeyEvent.VK_UP) knuckles.setUp(false); + if(k == KeyEvent.VK_DOWN) knuckles.setDown(false); + if(k == KeyEvent.VK_W) knuckles.setJumping(false); + if(k == KeyEvent.VK_E) knuckles.setGliding(false); + } + +} + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/GameState/MenuState.java b/Knuckle's Adventure/src/GameState/MenuState.java new file mode 100644 index 0000000..1748f56 --- /dev/null +++ b/Knuckle's Adventure/src/GameState/MenuState.java @@ -0,0 +1,77 @@ +package GameState; + +import Audio.AudioPlayer; +import TileMap.Background; + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; + +import javax.imageio.ImageIO; + +public class MenuState extends GameState { + + private Background bg; + private BufferedImage icon; + + private Font font; + private AudioPlayer bgMusic; + + public MenuState(GameStateManager gsm) { + + this.gsm = gsm; + +try { + + //Loads Background + bg = new Background("/Menu/Island_Background2.gif", 1); + bg.setVector(-0.125, 0); + //Loads Emblem + icon = ImageIO.read(getClass().getResourceAsStream("/Menu/Emblem2.gif")); + font = new Font("Times New Roman", Font.PLAIN, 13); + + } catch(Exception e) { + e.printStackTrace(); + } + } + public void init() { + + bgMusic = new AudioPlayer("/Music/Intro.mp3"); + bgMusic.play(); + + } + + public void update() { + bg.update(); + } + + public void draw(Graphics2D g) { + + // draw bg + bg.draw(g); + g.drawImage(icon, 0, 0, null); + + g.setFont(font); + g.drawString("CSE 2102", 10, 510); + + + } + + public void keyPressed(int k) { + if(k == KeyEvent.VK_ENTER){ + gsm.setState(GameStateManager.LEVEL1STATE);} + } + + public void keyReleased(int k) {} + +} + + + + + + + + + + diff --git a/Knuckle's Adventure/src/Main/Game.java b/Knuckle's Adventure/src/Main/Game.java new file mode 100644 index 0000000..7b254a2 --- /dev/null +++ b/Knuckle's Adventure/src/Main/Game.java @@ -0,0 +1,18 @@ +package Main; + +import javax.swing.JFrame; + +public class Game { + + public static void main(String[] args) { + + JFrame window = new JFrame("Knuckle's Adventure"); + window.setContentPane(new GamePanel()); + window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + window.setResizable(true); + window.pack(); + window.setVisible(true); + + } + +} diff --git a/Knuckle's Adventure/src/Main/GamePanel.java b/Knuckle's Adventure/src/Main/GamePanel.java new file mode 100644 index 0000000..ea20b4d --- /dev/null +++ b/Knuckle's Adventure/src/Main/GamePanel.java @@ -0,0 +1,135 @@ +package Main; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.event.*; + +import javax.swing.JPanel; + +import GameState.GameStateManager; + +@SuppressWarnings("serial") +public class GamePanel extends JPanel + implements Runnable, KeyListener{ + + // dimensions + public static final int WIDTH = 950; + public static final int HEIGHT = 520; + public static final int SCALE = 2; + + // game thread + private Thread thread; + private boolean running; + private int FPS = 60; + private long targetTime = 1000 / FPS; + + // image + private BufferedImage image; + private Graphics2D g; + + // game state manager + private GameStateManager gsm; + + public GamePanel() { + super(); + setPreferredSize( + new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); + setFocusable(true); + requestFocus(); + } + + public void addNotify() { + super.addNotify(); + if(thread == null) { + thread = new Thread(this); + addKeyListener(this); + thread.start(); + } + } + + private void init() { + + image = new BufferedImage( + WIDTH, HEIGHT, + BufferedImage.TYPE_INT_RGB + ); + g = (Graphics2D) image.getGraphics(); + + running = true; + + gsm = new GameStateManager(); + + } + + public void run() { + + init(); + + long start; + long elapsed; + long wait; + + // game loop + while(running) { + + start = System.nanoTime(); + + update(); + draw(); + drawToScreen(); + + elapsed = System.nanoTime() - start; + + wait = targetTime - elapsed / 1000000; + if(wait < 0) wait = 5; + + try { + Thread.sleep(wait); + } + catch(Exception e) { + e.printStackTrace(); + } + + } + + } + + private void update() { + gsm.update(); + } + private void draw() { + gsm.draw(g); + } + private void drawToScreen() { + Graphics g2 = getGraphics(); + g2.drawImage(image, 0, 0, + WIDTH * SCALE, HEIGHT * SCALE, + null); + g2.dispose(); + } + + public void keyTyped(KeyEvent key) {} + public void keyPressed(KeyEvent key) { + gsm.keyPressed(key.getKeyCode()); + } + public void keyReleased(KeyEvent key) { + gsm.keyReleased(key.getKeyCode()); + } + +} + + + + + + + + + + + + + + + + diff --git a/Knuckle's Adventure/src/TileMap/Background.java b/Knuckle's Adventure/src/TileMap/Background.java new file mode 100644 index 0000000..9e323e5 --- /dev/null +++ b/Knuckle's Adventure/src/TileMap/Background.java @@ -0,0 +1,82 @@ +package TileMap; + +import Main.GamePanel; + +import java.awt.*; +import java.awt.image.*; +import javax.imageio.ImageIO; + +public class Background { + + private BufferedImage image; + + private double x; + private double y; + private double dx; + private double dy; + + private double moveScale; + + public Background(String s, double ms) { + + try { + image = ImageIO.read( + getClass().getResourceAsStream(s) + ); + moveScale = ms; + } + catch(Exception e) { + e.printStackTrace(); + } + + } + + public void setPosition(double x, double y) { + this.x = (x * moveScale) % GamePanel.WIDTH; + this.y = (y * moveScale) % GamePanel.HEIGHT; + } + + public void setVector(double dx, double dy) { + this.dx = dx; + this.dy = dy; + } + + public void update() { + x += dx; + y += dy; + } + + public void draw(Graphics2D g) { + + g.drawImage(image, (int)x, (int)y, null); + + if(x < 0) { + g.drawImage( + image, + + + + + (int)x + GamePanel.WIDTH, + (int)y, + null + ); + } + if(x > 0) { + g.drawImage( + image, + (int)x - GamePanel.WIDTH, + (int)y, + null + ); + } + } + +} + + + + + + + diff --git a/Knuckle's Adventure/src/TileMap/Tile.java b/Knuckle's Adventure/src/TileMap/Tile.java new file mode 100644 index 0000000..c339d47 --- /dev/null +++ b/Knuckle's Adventure/src/TileMap/Tile.java @@ -0,0 +1,22 @@ +package TileMap; + +import java.awt.image.BufferedImage; + +public class Tile { + + private BufferedImage image; + private int type; + + // tile types + public static final int NORMAL = 0; + public static final int BLOCKED = 1; + + public Tile(BufferedImage image, int type) { + this.image = image; + this.type = type; + } + + public BufferedImage getImage() { return image; } + public int getType() { return type; } + +} diff --git a/Knuckle's Adventure/src/TileMap/TileMap.java b/Knuckle's Adventure/src/TileMap/TileMap.java new file mode 100644 index 0000000..c9f54ce --- /dev/null +++ b/Knuckle's Adventure/src/TileMap/TileMap.java @@ -0,0 +1,210 @@ +package TileMap; + +import java.awt.*; +import java.awt.image.*; + +import java.io.*; +import javax.imageio.ImageIO; + +import Main.GamePanel; + +public class TileMap { + + // position + private double x; + private double y; + + // bounds + private int xmin; + private int ymin; + private int xmax; + private int ymax; + + private double tween; + + // map + private int[][] map; + private int tileSize; + private int numRows; + private int numCols; + private int width; + private int height; + + // tileset + private BufferedImage tileset; + private int numTilesAcross; + private Tile[][] tiles; + + // drawing + private int rowOffset; + private int colOffset; + private int numRowsToDraw; + private int numColsToDraw; + + public TileMap(int tileSize) { + this.tileSize = tileSize; + numRowsToDraw = GamePanel.HEIGHT / tileSize + 2; + numColsToDraw = GamePanel.WIDTH / tileSize + 2; + tween = 0.07; + } + + public void loadTiles(String s) { + + try { + + tileset = ImageIO.read( + getClass().getResourceAsStream(s) + ); + numTilesAcross = tileset.getWidth() / tileSize; + tiles = new Tile[2][numTilesAcross]; + + BufferedImage subimage; + for(int col = 0; col < numTilesAcross; col++) { + subimage = tileset.getSubimage( + col * tileSize, + 0, + tileSize, + tileSize + ); + tiles[0][col] = new Tile(subimage, Tile.NORMAL); + subimage = tileset.getSubimage( + col * tileSize, + tileSize, + tileSize, + tileSize + ); + tiles[1][col] = new Tile(subimage, Tile.BLOCKED); + } + + } + catch(Exception e) { + e.printStackTrace(); + } + + } + + public void loadMap(String s) { + + try { + + InputStream in = getClass().getResourceAsStream(s); + BufferedReader br = new BufferedReader( + new InputStreamReader(in) + ); + + numCols = Integer.parseInt(br.readLine()); + numRows = Integer.parseInt(br.readLine()); + map = new int[numRows][numCols]; + width = numCols * tileSize; + height = numRows * tileSize; + + xmin = GamePanel.WIDTH - width; + xmax = 0; + ymin = GamePanel.HEIGHT - height; + ymax = 0; + + String delims = "\\s+"; + for(int row = 0; row < numRows; row++) { + String line = br.readLine(); + String[] tokens = line.split(delims); + for(int col = 0; col < numCols; col++) { + map[row][col] = Integer.parseInt(tokens[col]); + } + } + + } + catch(Exception e) { + e.printStackTrace(); + } + + } + + public int getTileSize() { return tileSize; } + public double getx() { return x; } + public double gety() { return y; } + public int getWidth() { return width; } + public int getHeight() { return height; } + + public int getType(int row, int col) { + int rc = map[row][col]; + int r = rc / numTilesAcross; + int c = rc % numTilesAcross; + return tiles[r][c].getType(); + } + + public void setTween(double d) { tween = d; } + + public void setPosition(double x, double y) { + + this.x += (x - this.x) * tween; + this.y += (y - this.y) * tween; + + fixBounds(); + + colOffset = (int)-this.x / tileSize; + rowOffset = (int)-this.y / tileSize; + + } + + private void fixBounds() { + if(x < xmin) x = xmin; + if(y < ymin) y = ymin; + if(x > xmax) x = xmax; + if(y > ymax) y = ymax; + } + + public void draw(Graphics2D g) { + + for( + int row = rowOffset; + row < rowOffset + numRowsToDraw; + row++) { + + if(row >= numRows) break; + + for( + int col = colOffset; + col < colOffset + numColsToDraw; + col++) { + + if(col >= numCols) break; + + if(map[row][col] == 0) continue; + + int rc = map[row][col]; + int r = rc / numTilesAcross; + int c = rc % numTilesAcross; + + g.drawImage( + tiles[r][c].getImage(), + (int)x + col * tileSize, + (int)y + row * tileSize, + null + ); + + } + + } + + } + +} + + + + + + + + + + + + + + + + + + +