Мастер класс: создание игры на Java "Собери пасхальные яйца"

г.Северобайкальск МАОУ ДО «ДДТ «Эврика»
Педагог дополнительного образования
программирование на языке Java
Барабанщикова Анастасия Евгеньевна
Мастер-класс:
Создание игры с кроликом в Greenfoot (90 минут)
Мастер-класс: Создание игры с кроликом в Greenfoot
1. Подготовка проекта
Убедитесь, что у вас установлена среда разработки Greenfoot.
Создайте новый проект в Greenfoot.
Создайте классы Bunny, Egg, Platform и GameWorld, как в вашем коде.
Подготовьте изображения для кролика (bunny.png), яйца (egg.png), платформы (platform.png) и фона (background.png). Эти изображения должны быть в папке images вашего проекта.
НЕ ЗАБУДЬТЕ ПРОВЕСТИ ФИЗ МИНУТКИ

2. Описание классов
Класс Bunny

Свойства:
speed: скорость перемещения кролика.
jumpStrength: сила прыжка (отрицательное значение, так как ось Y в Greenfoot направлена вниз).
gravity: гравитация, которая увеличивает скорость падения.
velocity: текущая скорость падения.
Методы:
moveBunny(): обрабатывает движение кролика влево и вправо, а также прыжок при нажатии пробела.
applyGravity(): применяет гравитацию, заставляя кролика падать.
isOnGround(): проверяет, стоит ли кролик на платформе.
collectEgg(): собирает яйца, если кролик с ними сталкивается.
Класс Egg
Простое изображение яйца, которое кролик может собирать.

Класс Platform
Платформа, на которой кролик может стоять.

Класс GameWorld
Основной мир игры, где создаются объекты: кролик, яйца и платформы.


3. Как работает код
Движение кролика:
При нажатии клавиш "влево" и "вправо" кролик перемещается по горизонтали.
При нажатии пробела кролик прыгает, если он стоит на платформе.
Гравитация:
Скорость падения (velocity) увеличивается на значение гравитации (gravity).
Если кролик стоит на платформе, его скорость падения обнуляется.
Сбор яиц:
Если кролик сталкивается с яйцом, оно удаляется из мира.

4. Проверка кода
Убедитесь, что все изображения (bunny.png, egg.png, platform.png, background.png) загружены в проект.
Запустите мир GameWorld. Кролик должен двигаться, прыгать и собирать яйца.
import greenfoot.*; // Импортируембиблиотеку Greenfoot
public class Bunny extends Actor {
private int speed = 4; // Скоростьперемещения
privateintjumpStrength = -12; // Сила прыжка (отрицательное значение - вверх)
private int gravity = 1; // Гравитация
privateintvelocity = 0; // Текущая скорость падения
public void act() {
moveBunny();
applyGravity();
collectEgg();
}
private void moveBunny() {
if (Greenfoot.isKeyDown("left")) {
move(-speed);
}
if (Greenfoot.isKeyDown("right")) {
move(speed);
}
if (Greenfoot.isKeyDown("space") && isOnGround()) {
velocity = jumpStrength; // Прыгаем, если на земле
}
}
private void applyGravity() {
velocity += gravity;
setLocation(getX(), getY() + velocity);
if (isOnGround()) {
velocity = 0;
}
}
private boolean isOnGround() {
return getOneObjectAtOffset(0, getImage().getHeight()/2, Platform.class) != null;
}
private void collectEgg() {
Egg egg = (Egg) getOneIntersectingObject(Egg.class);
if (egg != null) {
getWorld().removeObject(egg);
}
}
}
class Egg extends Actor {
public Egg() {
setImage("egg.png");
}
}
class Platform extends Actor {
public Platform() {
setImage("platform.png");
}
}
class GameWorld extends World {
public GameWorld() {
super(800, 600, 1);
setBackground("background.png");
Bunny bunny = new Bunny();
addObject(bunny, 100, 500);
for (int i = 0; i < 5; i++) {
addObject(new Egg(), Greenfoot.getRandomNumber(800), Greenfoot.getRandomNumber(400));
}
for (int i = 0; i < 3; i++) {
addObject(new Platform(), 200 + i * 200, 400);
}
}
}

5. Возможные улучшения
Добавление счёта:
Создайте переменную score в классе Bunny и увеличивайте её при сборе яиц.
Отображайте счёт на экране.
private int score = 0;
private void collectEgg() {
Egg egg = (Egg) getOneIntersectingObject(Egg.class);
if (egg != null) {
getWorld().removeObject(egg);
score++;
System.out.println("Счёт: " + score);
}
}
Добавление врагов:
Создайте класс Enemy, который будет двигаться по платформам. Если кролик сталкивается с врагом, игра заканчивается.
import greenfoot.*;
public class Enemy extends Actor {
private int speed = 2; // Скорость движения врага
private int direction = 1; // Направление движения: 1 - вправо, -1 - влево
public void act() {
moveAlongPlatform();
checkCollisionWithBunny();
}
private void moveAlongPlatform() {
// Двигаем врага в текущем направлении
setLocation(getX() + speed * direction, getY());
// Проверяем, находится ли враг на платформе
if (!isOnPlatform()) {
// Если враг достиг края платформы, меняем направление
direction *= -1;
setLocation(getX() + speed * direction, getY()); // Возвращаемвраганаплатформу
}
}
private boolean isOnPlatform() {
// Проверяем, находится ли враг на платформе
return getOneObjectAtOffset(0, getImage().getHeight() / 2, Platform.class) != null;
}
private void checkCollisionWithBunny() {
// Проверяем столкновение с кроликом
if (isTouching(Bunny.class)) {
Greenfoot.stop(); // Останавливаем игру
getWorld().showText("Играокончена!Врагпоймалвас.", getWorld().getWidth() / 2, getWorld().getHeight() / 2);
}
}
}
Обновление класса GameWorld
Добавим врага в мир игры. Например, разместим его на одной из платформ.
class GameWorld extends World {
private int time = 60; // Начальноевремя (например, 60 секунд)
private int score = 0; // Счётчиксобранныхяиц
private Label timeLabel; // Метка для отображения времени
private Label scoreLabel; // Метка для отображения счёта
public GameWorld() {
super(800, 600, 1);
setBackground("background.png");
//Создаемкролика
Bunny bunny = new Bunny();
addObject(bunny, 100, 500);
//Создаемяйца
for (int i = 0; i < 5; i++) {
addObject(new Egg(), Greenfoot.getRandomNumber(800), Greenfoot.getRandomNumber(400));
}
//Создаемплатформы
for (int i = 0; i < 3; i++) {
addObject(new Platform(), 200 + i * 200, 400);
}
// Создаем врага и размещаем его на платформе
Enemy enemy = new Enemy();
addObject(enemy, 300, 400 - enemy.getImage().getHeight() / 2);
// Создаем метки для отображения времени и счёта
timeLabel = new Label("Время: " + time, 30);
addObject(timeLabel, 100, 30);
scoreLabel = new Label("Счёт: " + score, 30);
addObject(scoreLabel, 700, 30);
}
public void act() {
updateTimer();
checkGameOver();
}
private void updateTimer() {
if (time > 0) {
time--;
timeLabel.setValue("Время: " + time);
}
}
private void checkGameOver() {
if (time <= 0) {
showText("Времявышло!Играокончена.", getWidth() / 2, getHeight() / 2);
Greenfoot.stop(); // Останавливаем игру
} else if (score >= 5) { // Если собраны все яйца
showText("Победа! Вы собрали все яйца.", getWidth() / 2, getHeight() / 2);
Greenfoot.stop();
}
}
public void increaseScore() {
score++;
scoreLabel.setValue("Счёт: " + score);
}
}
Объяснение работы врага
Движение по платформе:
Враг двигается влево и вправо с заданной скоростью (speed).
Если враг достигает края платформы, он меняет направление (direction).
Проверка нахождения на платформе:
Метод isOnPlatform() проверяет, находится ли враг на платформе, используя getOneObjectAtOffset.
Столкновение с кроликом:
Если враг сталкивается с кроликом, игра завершается, и на экране появляется сообщение.
Анимация прыжка:
Добавьте анимацию прыжка, меняя изображение кролика при прыжке.
Подготовка изображений
Подготовьте несколько изображений для анимации прыжка. Например:
bunny-stand.png — кролик стоит.
bunny-jump-up.png — кролик прыгает вверх.
bunny-jump-down.png — кролик падает.
Разместите эти изображения в папке images вашего проекта.

Обновление класса Bunny
Добавим переменные для хранения изображений и логику переключения анимации.
importgreenfoot.*;
publicclassBunnyextendsActor{
privateint speed =4;//Скоростьперемещения
privateint jumpStrength =-12;//Силапрыжка (отрицательноезначение - вверх)
privateint gravity =1;//Гравитация
privateint velocity =0;//Текущаяскоростьпадения
//Изображениядляанимации
privateGreenfootImage standImage =newGreenfootImage("bunny-stand.png");
privateGreenfootImage jumpUpImage =newGreenfootImage("bunny-jump-up.png");
privateGreenfootImage jumpDownImage =newGreenfootImage("bunny-jump-down.png");
public Bunny() {
setImage(standImage); // Устанавливаем начальное изображение
}
publicvoidact(){
moveBunny();
applyGravity();
updateAnimation();
collectEgg();
}
privatevoidmoveBunny(){
if(Greenfoot.isKeyDown("left")){
move(-speed);
}
if(Greenfoot.isKeyDown("right")){
move(speed);
}
if(Greenfoot.isKeyDown("space")&&isOnGround()){
velocity = jumpStrength; // Прыгаем, если на земле
}
}
private void applyGravity() {
velocity+= gravity;
setLocation(getX(),getY()+ velocity);
if(isOnGround()){
velocity=0;
}
}
privatebooleanisOnGround(){
returngetOneObjectAtOffset(0,getImage().getHeight()/2,Platform.class)!=null;
}
private void collectEgg() {
Egg egg =(Egg)getOneIntersectingObject(Egg.class);
if(egg!=null){
getWorld().removeObject(egg);
((GameWorld) getWorld()).increaseScore(); // Увеличиваем счёт
}
}
privatevoidupdateAnimation(){
if(velocity<0){
//Кроликдвижетсявверх (прыжок)
setImage(jumpUpImage);
}elseif(velocity>0){
//Кроликпадает
setImage(jumpDownImage);
} else {
// Кролик стоит на платформе
setImage(standImage);
}
}
}
Объяснение изменений
Изображения:
Мы добавили три изображения: для стояния, прыжка вверх и падения.
В конструкторе Bunny устанавливаем начальное изображение (standImage).
Анимация:
Метод updateAnimation() проверяет значение velocity:
Если velocity < 0, кролик движется вверх (прыжок), и мы устанавливаем изображение jumpUpImage.
Если velocity > 0, кролик падает, и мы устанавливаем изображение jumpDownImage.
Если velocity == 0, кролик стоит на платформе, и мы устанавливаем изображение standImage.
Добавим таймер в нашу игру! Таймер будет отсчитывать время с момента начала игры, и игрок должен будет собрать все яйца до того, как время истечёт. Вот как это можно реализовать:

1. Добавление таймера в класс GameWorld
В классе GameWorld добавим переменные для хранения времени и методы для работы с таймером.
class GameWorld extends World {
private int time = 60; // Начальное время (например, 60 секунд)
private int score = 0; // Счётчиксобранныхяиц
private Label timeLabel; // Метка для отображения времени
private Label scoreLabel; // Метка для отображения счёта
public GameWorld() {
super(800, 600, 1);
setBackground("background.png");
// Создаем кролика
Bunny bunny = new Bunny();
addObject(bunny, 100, 500);
// Создаем яйца
for (int i = 0; i < 5; i++) {
addObject(new Egg(), Greenfoot.getRandomNumber(800), Greenfoot.getRandomNumber(400));
}
// Создаем платформы
for (int i = 0; i < 3; i++) {
addObject(new Platform(), 200 + i * 200, 400);
}
// Создаем метки для отображения времени и счёта
timeLabel = new Label("Время: " + time, 30);
addObject(timeLabel, 100, 30);
scoreLabel = new Label("Счёт: " + score, 30);
addObject(scoreLabel, 700, 30);
}
public void act() {
updateTimer();
checkGameOver();
}
private void updateTimer() {
if (time > 0) {
time--;
timeLabel.setValue("Время: " + time); }}
private void checkGameOver() {
if (time <= 0) {
showText("Время вышло! Игра окончена.", getWidth() / 2, getHeight() / 2);
Greenfoot.stop(); // Останавливаем игру
}}
public void increaseScore() {
score++;
scoreLabel.setValue("Счёт: " + score);
}}
2. Обновление класса Bunny для работы с таймером
Теперь добавим в класс Bunny вызов метода increaseScore() из GameWorld при сборе яйца.
private void collectEgg() {
Egg egg = (Egg) getOneIntersectingObject(Egg.class);
if (egg != null) {
getWorld().removeObject(egg);
((GameWorld) getWorld()).increaseScore(); // Увеличиваемсчёт
}
}
3. Объяснение изменений
Таймер:
В классе GameWorld добавлена переменная time, которая отсчитывает время.
Каждый акт (кадр) время уменьшается на 1.
Когда время достигает 0, игра останавливается.
Счёт:
В классе GameWorld добавлена переменная score, которая хранит количество собранных яиц.
Метод increaseScore() увеличивает счёт и обновляет метку на экране.
Метки:
Используются класс Label для отображения времени и счёта на экране.

4. Запуск и тестирование
Запустите игру. На экране появятся метки с временем и счётом.
Собирайте яйца, чтобы увеличить счёт.
Если время истечёт до того, как все яйца будут собраны, игра завершится.

5. Возможные улучшения
Добавление победы:
Если игрок соберёт все яйца до истечения времени, покажите сообщение о победе.
private void checkGameOver() {
if (time <= 0) {
showText("Время вышло! Игра окончена.", getWidth() / 2, getHeight() / 2);
Greenfoot.stop();
} else if (score >= 5) { // Если собраны все яйца
showText("Победа! Вы собрали все яйца.", getWidth() / 2, getHeight() / 2);
Greenfoot.stop(); }}
Чтобы оставлять комментарии, вам необходимо авторизоваться на сайте. Если у вас еще нет учетной записи на нашем сайте, предлагаем зарегистрироваться. Это займет не более 5 минут.