게임만들기(2) - "JAVADOT" 플랫폼게임
2021. 7. 9. 01:58ㆍ프로그래밍/개인프로젝트
JavaUI를 이용해서 플랫폼게임을 만드는 과정을 기록합니다.
package JAVADOT_pkg;
import java.util.ArrayList;
import java.util.HashMap;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class JAVADOT_ver2 extends Application {
private HashMap<KeyCode, Boolean> keys = new HashMap<KeyCode, Boolean>();
private ArrayList<Node> blocks = new ArrayList<Node>();
private ArrayList<Node> energys = new ArrayList<Node>();
private ArrayList<Node> doors = new ArrayList<Node>();
private Node player;
private int levelWidth;
private Point2D playerVelocity = new Point2D(0, 0);
private boolean canJump = true;
private Pane mainContainer = new Pane();
private Pane blockContainer = new Pane();
private Node createObject(int x, int y, int w, int h, Color color) {
Rectangle object = new Rectangle(w, h);
object.setTranslateX(x);
object.setTranslateY(y);
object.setFill(color);
blockContainer.getChildren().addAll(object);
return object;
}
// player, block, energy, door등 사각형 객체를 만드는 클래스
private void MainPage() {
Rectangle bg = new Rectangle(1280, 720, Color.LIGHTGOLDENRODYELLOW);
// 배경화면만드는 클래스
levelWidth = ObjectData.LEVEL1[0].length() * 10;
// 총 맵 길이
for (int i = 0; i < ObjectData.LEVEL1.length; i++) {
// 같은 패키지의 ObjectData파일 참조해서 맵 생성
String line = ObjectData.LEVEL1[i];
for (int j = 0; j < line.length(); j++) {
switch (line.charAt(j)) {
case '0': // 0이면 빈공간
break;
case '1': // 1이면 block
Node block = createObject(j*10, i*10, 10, 10, Color.LIGHTGREEN);
blocks.add(block);
break;
case '2': // 2면 energy
Node energy = createObject(j*10, i*10, 5, 5, Color.ORANGE);
energys.add(energy);
break;
case '3': // 3이면 door
Node door = createObject(j*10, i*10, 10, 10, Color.BLACK);
doors.add(door);
break;
}
}
}
player = createObject(0, 600, 20, 20, Color.DODGERBLUE);
// player객체 생성
player.translateXProperty().addListener((obs, old, newValue) -> {
int offset = newValue.intValue();
if (offset > 640 && offset < levelWidth - 640) {
blockContainer.setLayoutX(-(offset - 640));
//player객체의 X좌표값이 화면절반넘어가면 blockContainer의 위치이동
}
});
mainContainer.getChildren().addAll(bg, blockContainer);
// mainContainer에 bg와 blockContainer를 자식으로 지정해준다
}
private boolean isPressed(KeyCode key) {
return keys.getOrDefault(key, false);
//keys객체를 만드는 HashMap클래스에 쓰이는 메소드
//key가 존재하면 key값을 반환, 존재하지않으면 false 반환
}
private void sceneUpdate() { // AnimationTimer로 프레임마다 체크
if (isPressed(KeyCode.LEFT) && player.getTranslateX() > 0) {
movePlayerX(-6);
}
// 조건이 참이면 movePlayerX의 매개변수로 -6를 입력
if (isPressed(KeyCode.RIGHT) && player.getTranslateX() + 40 <= levelWidth - 5) {
movePlayerX(6);
}
// 조건이 참이면 movePlayerX의 매개변수로 6를 입력
if (isPressed(KeyCode.SPACE) && player.getTranslateY() > -100) {
jumpPlayer();
// 조건이 참이면 jumpPlayer()메소드 실행
if (playerVelocity.getY() < 10) {
playerVelocity = playerVelocity.add(0, 2); //playerVelocity의 y값이 10보다 작으면 1프레임당 y값 1씩추가
}
movePlayerY((int)playerVelocity.getY()); //movePlayerY(int value)에 playerVelocity값 할당 (낙하담당값이라서 연속적으로 실행되야함)
// 조건이 참이면 playerVelocity에 (0,2) 더해준다
// movePlayerY에 값 전달
}
private void movePlayerX(int value) {
boolean movingRight = value > 0; // LEFT=false, RIGHT=true
for (int i = 0; i < Math.abs(value); i++) {
for (Node block : blocks) {
if (player.getBoundsInParent().intersects(block.getBoundsInParent())) {
if (movingRight) { //RIGHT
if (player.getTranslateX() + 20 == block.getTranslateX()) {
// RIGHT 이동시 player의 'x값+20'이 block의 x값과 같다면
if(player.getTranslateY()+10 < block.getTranslateY()) {
// player의 y값+10이 block의 y값보다 작다면
player.setTranslateY(player.getTranslateY()-10);
// player의 y값을 -10해준다
}
return;
}
} else { //LEFT
if (player.getTranslateX() == block.getTranslateX() + 10) {
// LEFT 이동시 player의 x값과 block의 x값+10이 같다면
if(player.getTranslateY()+10 < block.getTranslateY()) {
// player의 y값+10이 block의 y값보다 작다면 y값을 -10해준다
player.setTranslateY(player.getTranslateY()-10);
}
return;
}
}
}
}
player.setTranslateX(player.getTranslateX()+(movingRight ? 1 : -1));
// RIGHT버튼을 누르면 player객체의 x위치를 +1만큼씩, LEFT버튼을 누르면 x위치를 -1만큼씩이동
}
for (Node energy : energys) { //일단은 구현만 해놓고 다음에 변경
if (player.getBoundsInParent().intersects(door.getBoundsInParent())) {
System.out.println("energy touch");
}
}
for (Node door : doors) { //일단은 구현만 해놓고 다음에 변경
if (player.getBoundsInParent().intersects(door.getBoundsInParent())) {
System.out.println("door touch");
}
}
}
private void movePlayerY(int value) {
boolean movingDown = value > 0;
for (int i = 0; i < Math.abs(value); i++) {
for (Node block : blocks) {
if (player.getBoundsInParent().intersects(block.getBoundsInParent())) {
//player와 block비교
if (movingDown) {
if (player.getTranslateY() + 20 == block.getTranslateY()) {
// player객체 y값 +20(객체높이) = block객체 y값이면
player.setTranslateY(player.getTranslateY() - 1);
canJump=true;
// player객체의 y값을 -1해주고 canJump메소드 활성화
return;
}
} else {
if (player.getTranslateY() == block.getTranslateY() + 9) {
canJump=false;
// 점프시 윗벽이 막혀있으면 더 안올라가짐
return;
}
}
}
}
player.setTranslateY(player.getTranslateY()+(movingDown ? 1 : -1));
//player객체의 위치 = player객체의 이동좌표+ movingDown이 참이라면 +1 거짓이면 -1
}
for (Node door : energys) { //일단은 구현만 해놓고 다음에 변경
if (player.getBoundsInParent().intersects(door.getBoundsInParent())) {
System.out.println("energy touch");
}
}
for (Node door : doors) { //일단은 구현만 해놓고 다음에 변경
if (player.getBoundsInParent().intersects(door.getBoundsInParent())) {
System.out.println("door touch");
}
}
}
//
private void jumpPlayer() {
if (canJump) {
playerVelocity = playerVelocity.add(0, -35);
canJump = false;
}
}
//
@Override
public void start(Stage primaryStage) {
MainPage();
Scene scene = new Scene(mainContainer);
scene.setOnKeyPressed(e -> keys.put(e.getCode(), true));
scene.setOnKeyReleased(e -> keys.put(e.getCode(), false));
primaryStage.setTitle("JAVADOT");
primaryStage.setScene(scene);
primaryStage.show();
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
sceneUpdate();
}
};
timer.start();
}
public static void main(String[] args) {
launch(args);
}
}
오늘 한 것 :
ArrayList를 이용해서 각종 객체 구현,
player객체 좌/우 이동구현, 점프구현, 경사이동구현, 낙하구현, 이동시 화면이동구현
player 와 block 충돌구현,
내일 할 것 :
점프횟수제한 (1이상일때만 점프가능, 점프시 -1, Label객체를 통해 시각화)
player와 energy 충돌구현( 획득시 점프횟수 +1, 충돌시 사라지게하기)
'프로그래밍 > 개인프로젝트' 카테고리의 다른 글
게임만들기(4) - "JAVADOT" 플랫폼게임 (0) | 2021.07.14 |
---|---|
게임만들기(3) - "JAVADOT" 플랫폼게임 (0) | 2021.07.12 |
게임만들기(1) - "JAVADOT" 플랫폼게임 (0) | 2021.07.08 |
변수의 기본형 데이터 타입 사용시 (효율중시, 성능중시) (0) | 2021.06.22 |
(JavaFX) - Event Handler (0) | 2021.06.20 |