Dino Game
2
.gitignore
vendored
@@ -25,3 +25,5 @@ replay_pid*
|
|||||||
|
|
||||||
# Visual Studio Code settings.json
|
# Visual Studio Code settings.json
|
||||||
settings.json
|
settings.json
|
||||||
|
# IntelliJ Idea
|
||||||
|
.idea/*
|
||||||
10
DinoGame/.classpath
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="module" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
||||||
8
DinoGame/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
9
DinoGame/.idea/artifacts/DinoGame_jar.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="ArtifactManager">
|
||||||
|
<artifact type="jar" name="DinoGame:jar">
|
||||||
|
<output-path>$PROJECT_DIR$/bin/artifacts/DinoGame_jar</output-path>
|
||||||
|
<root id="archive" name="DinoGame.jar">
|
||||||
|
<element id="module-output" name="DinoGame" />
|
||||||
|
<element id="dir-copy" path="$PROJECT_DIR$/resources" />
|
||||||
|
</root>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
6
DinoGame/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
DinoGame/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/DinoGame.iml" filepath="$PROJECT_DIR$/DinoGame.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
DinoGame/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
28
DinoGame/.project
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>DinoGame</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
<filteredResources>
|
||||||
|
<filter>
|
||||||
|
<id>1758261738047</id>
|
||||||
|
<name></name>
|
||||||
|
<type>30</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||||
|
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
</filteredResources>
|
||||||
|
</projectDescription>
|
||||||
14
DinoGame/DinoGame.iml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<output url="file://$MODULE_DIR$/bin/Release/DinoGame" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/bin/Debug/DinoGame" />
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
BIN
DinoGame/resources/all-sprites.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
6
DinoGame/resources/best-scores.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
result=21,date=20200420_144048,player=Dino
|
||||||
|
result=58,date=20200420_144054,player=Dino
|
||||||
|
result=328,date=20200420_144126,player=Dino
|
||||||
|
result=367,date=20200422_130458,player=Dino
|
||||||
|
result=408,date=20200425_162524,player=Dino
|
||||||
|
result=537,date=20200425_164524,player=Dino
|
||||||
BIN
DinoGame/resources/bird-fly-1.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/bird-fly-2.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-1.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-2.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-3.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-4.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-5.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-6.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-7.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/cactus-8.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/cactus-9.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/cloud.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
DinoGame/resources/dead.wav
Normal file
BIN
DinoGame/resources/dino-dead.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/dino-down-run-1.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/dino-down-run-2.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/dino-jump.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/dino-run-1.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/dino-run-2.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/game-over.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/hi.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
DinoGame/resources/intro-text.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/jump.wav
Normal file
BIN
DinoGame/resources/land.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
DinoGame/resources/numbers.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
DinoGame/resources/paused.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
DinoGame/resources/replay.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
DinoGame/resources/scoreup.wav
Normal file
466
DinoGame/src/DinoGame.java
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
import javax.sound.sampled.*;
|
||||||
|
|
||||||
|
public class DinoGame extends JPanel implements ActionListener, KeyListener {
|
||||||
|
// Game constants
|
||||||
|
private static final int WIDTH = 800;
|
||||||
|
private static final int HEIGHT = 400;
|
||||||
|
private static final int GROUND_Y = 320;
|
||||||
|
private static final int FPS = 60;
|
||||||
|
private static final int GRAVITY = 2;
|
||||||
|
private static final int JUMP_STRENGTH = -22;
|
||||||
|
|
||||||
|
// Game state
|
||||||
|
private Timer timer;
|
||||||
|
private boolean gameStarted = false;
|
||||||
|
private boolean gameOver = false;
|
||||||
|
private boolean paused = false;
|
||||||
|
private int score = 0;
|
||||||
|
private int highScore = 0;
|
||||||
|
private double gameSpeed = 12.0;
|
||||||
|
private int frameCount = 0;
|
||||||
|
|
||||||
|
// Player
|
||||||
|
private int dinoX = 50;
|
||||||
|
private int dinoY = GROUND_Y - 90;
|
||||||
|
private int dinoWidth = 44;
|
||||||
|
private int dinoHeight = 47;
|
||||||
|
private int velocityY = 0;
|
||||||
|
private boolean isJumping = false;
|
||||||
|
private boolean isDucking = false;
|
||||||
|
private int animFrame = 0;
|
||||||
|
|
||||||
|
// Images
|
||||||
|
private BufferedImage dinoRun1, dinoRun2, dinoJump, dinoDead;
|
||||||
|
private BufferedImage dinoDownRun1, dinoDownRun2;
|
||||||
|
private BufferedImage cactus1, cactus2, cactus3, cactus4, cactus5, cactus6;
|
||||||
|
private BufferedImage birdFly1, birdFly2;
|
||||||
|
private BufferedImage cloud, land, gameOverImg, replayImg, hiImg;
|
||||||
|
|
||||||
|
// Game objects
|
||||||
|
private ArrayList<Obstacle> obstacles = new ArrayList<>();
|
||||||
|
private ArrayList<Cloud> clouds = new ArrayList<>();
|
||||||
|
private int landX = 0;
|
||||||
|
private Random rand = new Random();
|
||||||
|
private int obstacleTimer = 0;
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
private Clip jumpSound, deadSound, scoreSound;
|
||||||
|
|
||||||
|
public DinoGame() {
|
||||||
|
setPreferredSize(new Dimension(WIDTH, HEIGHT));
|
||||||
|
setBackground(Color.WHITE);
|
||||||
|
setFocusable(true);
|
||||||
|
addKeyListener(this);
|
||||||
|
|
||||||
|
loadImages();
|
||||||
|
loadSounds();
|
||||||
|
loadHighScore();
|
||||||
|
|
||||||
|
// Initialize clouds
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
clouds.add(new Cloud(rand.nextInt(WIDTH), 50 + rand.nextInt(100)));
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = new Timer(1000 / FPS, this);
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadImages() {
|
||||||
|
try {
|
||||||
|
dinoRun1 = ImageIO.read(getClass().getResourceAsStream("/dino-run-1.png"));
|
||||||
|
dinoRun2 = ImageIO.read(getClass().getResourceAsStream("/dino-run-2.png"));
|
||||||
|
dinoJump = ImageIO.read(getClass().getResourceAsStream("/dino-jump.png"));
|
||||||
|
dinoDead = ImageIO.read(getClass().getResourceAsStream("/dino-dead.png"));
|
||||||
|
dinoDownRun1 = ImageIO.read(getClass().getResourceAsStream("/dino-down-run-1.png"));
|
||||||
|
dinoDownRun2 = ImageIO.read(getClass().getResourceAsStream("/dino-down-run-2.png"));
|
||||||
|
|
||||||
|
cactus1 = ImageIO.read(getClass().getResourceAsStream("/cactus-1.png"));
|
||||||
|
cactus2 = ImageIO.read(getClass().getResourceAsStream("/cactus-2.png"));
|
||||||
|
cactus3 = ImageIO.read(getClass().getResourceAsStream("/cactus-3.png"));
|
||||||
|
cactus4 = ImageIO.read(getClass().getResourceAsStream("/cactus-4.png"));
|
||||||
|
cactus5 = ImageIO.read(getClass().getResourceAsStream("/cactus-5.png"));
|
||||||
|
cactus6 = ImageIO.read(getClass().getResourceAsStream("/cactus-6.png"));
|
||||||
|
|
||||||
|
birdFly1 = ImageIO.read(getClass().getResourceAsStream("/bird-fly-1.png"));
|
||||||
|
birdFly2 = ImageIO.read(getClass().getResourceAsStream("/bird-fly-2.png"));
|
||||||
|
|
||||||
|
cloud = ImageIO.read(getClass().getResourceAsStream("/cloud.png"));
|
||||||
|
land = ImageIO.read(getClass().getResourceAsStream("/land.png"));
|
||||||
|
gameOverImg = ImageIO.read(getClass().getResourceAsStream("/game-over.png"));
|
||||||
|
replayImg = ImageIO.read(getClass().getResourceAsStream("/replay.png"));
|
||||||
|
hiImg = ImageIO.read(getClass().getResourceAsStream("/hi.png"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Error loading images: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSounds() {
|
||||||
|
try {
|
||||||
|
jumpSound = AudioSystem.getClip();
|
||||||
|
jumpSound.open(AudioSystem.getAudioInputStream(getClass().getResourceAsStream("/jump.wav")));
|
||||||
|
|
||||||
|
deadSound = AudioSystem.getClip();
|
||||||
|
deadSound.open(AudioSystem.getAudioInputStream(getClass().getResourceAsStream("/dead.wav")));
|
||||||
|
|
||||||
|
scoreSound = AudioSystem.getClip();
|
||||||
|
scoreSound.open(AudioSystem.getAudioInputStream(getClass().getResourceAsStream("/scoreup.wav")));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Error loading sounds: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadHighScore() {
|
||||||
|
try {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/best-scores.txt");
|
||||||
|
if (is != null) {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||||
|
String line = reader.readLine();
|
||||||
|
if (line != null) {
|
||||||
|
highScore = Integer.parseInt(line.trim());
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
highScore = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveHighScore() {
|
||||||
|
try {
|
||||||
|
// Save to user's home directory since resources folder is read-only
|
||||||
|
String userHome = System.getProperty("user.home");
|
||||||
|
File scoresFile = new File(userHome, "dino-best-scores.txt");
|
||||||
|
PrintWriter writer = new PrintWriter(new FileWriter(scoresFile));
|
||||||
|
writer.println(highScore);
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Error saving high score: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playSound(Clip clip) {
|
||||||
|
if (clip != null) {
|
||||||
|
try {
|
||||||
|
if (clip.isRunning()) {
|
||||||
|
clip.stop();
|
||||||
|
}
|
||||||
|
clip.setFramePosition(0);
|
||||||
|
clip.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Error playing audio: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (!gameStarted || paused) {
|
||||||
|
repaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameOver) {
|
||||||
|
frameCount++;
|
||||||
|
|
||||||
|
// Update score
|
||||||
|
if (frameCount % 6 == 0) {
|
||||||
|
score++;
|
||||||
|
if (score % 100 == 0) {
|
||||||
|
playSound(scoreSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase speed
|
||||||
|
if (frameCount % 600 == 0) {
|
||||||
|
gameSpeed += 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update dino
|
||||||
|
if (isJumping) {
|
||||||
|
velocityY += GRAVITY;
|
||||||
|
dinoY += velocityY;
|
||||||
|
|
||||||
|
if (dinoY >= GROUND_Y - 90) {
|
||||||
|
dinoY = GROUND_Y - 90;
|
||||||
|
isJumping = false;
|
||||||
|
velocityY = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animation
|
||||||
|
if (frameCount % 5 == 0) {
|
||||||
|
animFrame = (animFrame + 1) % 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update ground
|
||||||
|
landX -= (int)gameSpeed;
|
||||||
|
if (land != null && landX <= -land.getWidth()) {
|
||||||
|
landX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update clouds
|
||||||
|
for (Cloud c : clouds) {
|
||||||
|
c.x -= 2;
|
||||||
|
if (cloud != null && c.x < -cloud.getWidth()) {
|
||||||
|
c.x = WIDTH + rand.nextInt(200);
|
||||||
|
c.y = 50 + rand.nextInt(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn obstacles
|
||||||
|
obstacleTimer++;
|
||||||
|
if (obstacleTimer > 60 + rand.nextInt(60)) {
|
||||||
|
spawnObstacle();
|
||||||
|
obstacleTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update obstacles
|
||||||
|
for (int i = obstacles.size() - 1; i >= 0; i--) {
|
||||||
|
Obstacle obs = obstacles.get(i);
|
||||||
|
obs.x -= (int)gameSpeed;
|
||||||
|
|
||||||
|
if (obs.x < -obs.width) {
|
||||||
|
obstacles.remove(i);
|
||||||
|
} else if (checkCollision(obs)) {
|
||||||
|
gameOver = true;
|
||||||
|
playSound(deadSound);
|
||||||
|
if (score > highScore) {
|
||||||
|
highScore = score;
|
||||||
|
saveHighScore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnObstacle() {
|
||||||
|
int type = rand.nextInt(10);
|
||||||
|
if (type < 7) {
|
||||||
|
// Cactus
|
||||||
|
BufferedImage[] cacti = {cactus1, cactus2, cactus3, cactus4, cactus5, cactus6};
|
||||||
|
BufferedImage cactusImg = cacti[rand.nextInt(cacti.length)];
|
||||||
|
if (cactusImg != null) {
|
||||||
|
obstacles.add(new Obstacle(WIDTH, GROUND_Y - cactusImg.getHeight(),
|
||||||
|
cactusImg.getWidth(), cactusImg.getHeight(),
|
||||||
|
cactusImg, false));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Bird
|
||||||
|
if (birdFly1 != null) {
|
||||||
|
int birdY = GROUND_Y - 44 - rand.nextInt(2) * 80;
|
||||||
|
obstacles.add(new Obstacle(WIDTH, birdY, 46, 40, birdFly1, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkCollision(Obstacle obs) {
|
||||||
|
int dinoActualHeight = isDucking ? 26 : dinoHeight;
|
||||||
|
int dinoActualY = isDucking ? GROUND_Y - 90 : dinoY;
|
||||||
|
|
||||||
|
Rectangle dinoRect = new Rectangle(dinoX + 5, dinoActualY + 5,
|
||||||
|
dinoWidth - 10, dinoActualHeight - 10);
|
||||||
|
Rectangle obsRect = new Rectangle(obs.x + 5, obs.y + 5,
|
||||||
|
obs.width - 10, obs.height - 10);
|
||||||
|
|
||||||
|
return dinoRect.intersects(obsRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reset() {
|
||||||
|
gameOver = false;
|
||||||
|
gameStarted = true;
|
||||||
|
score = 0;
|
||||||
|
gameSpeed = 12.0;
|
||||||
|
frameCount = 0;
|
||||||
|
dinoY = GROUND_Y - 90;
|
||||||
|
velocityY = 0;
|
||||||
|
isJumping = false;
|
||||||
|
isDucking = false;
|
||||||
|
obstacles.clear();
|
||||||
|
obstacleTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
// Draw clouds
|
||||||
|
for (Cloud c : clouds) {
|
||||||
|
if (cloud != null) {
|
||||||
|
g2d.drawImage(cloud, c.x, c.y, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw ground
|
||||||
|
if (land != null) {
|
||||||
|
g2d.drawImage(land, landX, GROUND_Y, null);
|
||||||
|
g2d.drawImage(land, landX + land.getWidth(), GROUND_Y, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw ground line
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.fillRect(0, GROUND_Y - 2, WIDTH, 2);
|
||||||
|
|
||||||
|
// Draw dino
|
||||||
|
BufferedImage dinoImg;
|
||||||
|
if (gameOver) {
|
||||||
|
dinoImg = dinoDead;
|
||||||
|
} else if (isJumping) {
|
||||||
|
dinoImg = dinoJump;
|
||||||
|
} else if (isDucking) {
|
||||||
|
dinoImg = (animFrame == 0) ? dinoDownRun1 : dinoDownRun2;
|
||||||
|
} else {
|
||||||
|
dinoImg = (animFrame == 0) ? dinoRun1 : dinoRun2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dinoImg != null) {
|
||||||
|
if (isDucking) {
|
||||||
|
g2d.drawImage(dinoImg, dinoX, GROUND_Y - 26, 59, 26, null);
|
||||||
|
} else {
|
||||||
|
g2d.drawImage(dinoImg, dinoX, dinoY, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw obstacles
|
||||||
|
for (Obstacle obs : obstacles) {
|
||||||
|
if (obs.isBird) {
|
||||||
|
BufferedImage birdImg = (frameCount % 10 < 5) ? birdFly1 : birdFly2;
|
||||||
|
if (birdImg != null) {
|
||||||
|
g2d.drawImage(birdImg, obs.x, obs.y, null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (obs.img != null) {
|
||||||
|
g2d.drawImage(obs.img, obs.x, obs.y, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw score
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.setFont(new Font("Courier New", Font.BOLD, 16));
|
||||||
|
if (hiImg != null && highScore > 0) {
|
||||||
|
g2d.drawImage(hiImg, WIDTH - 200, 20, null);
|
||||||
|
g2d.drawString(String.format("%05d", highScore), WIDTH - 150, 35);
|
||||||
|
}
|
||||||
|
g2d.drawString(String.format("%05d", score), WIDTH - 80, 35);
|
||||||
|
|
||||||
|
// Draw game over
|
||||||
|
if (gameOver) {
|
||||||
|
if (gameOverImg != null) {
|
||||||
|
g2d.drawImage(gameOverImg, WIDTH / 2 - gameOverImg.getWidth() / 2, 100, null);
|
||||||
|
}
|
||||||
|
if (replayImg != null) {
|
||||||
|
g2d.drawImage(replayImg, WIDTH / 2 - replayImg.getWidth() / 2, 150, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw start message
|
||||||
|
if (!gameStarted) {
|
||||||
|
g2d.setFont(new Font("Arial", Font.BOLD, 20));
|
||||||
|
g2d.drawString("Press SPACE to Start", WIDTH / 2 - 120, HEIGHT / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw pause
|
||||||
|
if (paused) {
|
||||||
|
g2d.setFont(new Font("Arial", Font.BOLD, 30));
|
||||||
|
g2d.drawString("PAUSED", WIDTH / 2 - 60, HEIGHT / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
int key = e.getKeyCode();
|
||||||
|
|
||||||
|
if (key == KeyEvent.VK_SPACE) {
|
||||||
|
if (!gameStarted) {
|
||||||
|
gameStarted = true;
|
||||||
|
} else if (gameOver) {
|
||||||
|
reset();
|
||||||
|
} else if (!isJumping && !isDucking) {
|
||||||
|
isJumping = true;
|
||||||
|
velocityY = JUMP_STRENGTH;
|
||||||
|
playSound(jumpSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == KeyEvent.VK_DOWN && !isJumping && gameStarted && !gameOver) {
|
||||||
|
isDucking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == KeyEvent.VK_P && gameStarted && !gameOver) {
|
||||||
|
paused = !paused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
|
||||||
|
isDucking = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {}
|
||||||
|
|
||||||
|
private class Obstacle {
|
||||||
|
int x, y, width, height;
|
||||||
|
BufferedImage img;
|
||||||
|
boolean isBird;
|
||||||
|
|
||||||
|
Obstacle(int x, int y, int width, int height, BufferedImage img, boolean isBird) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.img = img;
|
||||||
|
this.isBird = isBird;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Cloud {
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
Cloud(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JFrame frame = new JFrame("Chrome Dino Game");
|
||||||
|
try {
|
||||||
|
BufferedImage icon = ImageIO.read(DinoGame.class.getResourceAsStream("/dino-jump.png"));
|
||||||
|
frame.setIconImage(icon);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Errore caricamento icona: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
DinoGame game = new DinoGame();
|
||||||
|
frame.add(game);
|
||||||
|
frame.pack();
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setLocationRelativeTo(null);
|
||||||
|
frame.setResizable(false);
|
||||||
|
frame.setVisible(true);
|
||||||
|
});
|
||||||
|
} catch (Exception e){
|
||||||
|
System.err.println("Error : " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
PrimaGUI/README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Welcome to the VS Code Java world. Here is a guideline to help you get started to write Java code in Visual Studio Code.
|
||||||
|
|
||||||
|
## Folder Structure
|
||||||
|
|
||||||
|
The workspace contains two folders by default, where:
|
||||||
|
|
||||||
|
- `src`: the folder to maintain sources
|
||||||
|
- `lib`: the folder to maintain dependencies
|
||||||
|
|
||||||
|
Meanwhile, the compiled output files will be generated in the `bin` folder by default.
|
||||||
|
|
||||||
|
> If you want to customize the folder structure, open `.vscode/settings.json` and update the related settings there.
|
||||||
|
|
||||||
|
## Dependency Management
|
||||||
|
|
||||||
|
The `JAVA PROJECTS` view allows you to manage your dependencies. More details can be found [here](https://github.com/microsoft/vscode-java-dependency#manage-dependencies).
|
||||||
14
PrimaGUI/src/App.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
JFrame f = new JFrame("Una finestra meravigliosa");
|
||||||
|
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
f.setBounds(100,100,800,600);
|
||||||
|
f.setLayout(null);
|
||||||
|
JButton b = new JButton("ok");
|
||||||
|
b.setBounds(100, 20, 100, 30);
|
||||||
|
f.add(b);
|
||||||
|
f.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||