Skip to content

Instantly share code, notes, and snippets.

@bartoleo
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bartoleo/3392215d144130164a04 to your computer and use it in GitHub Desktop.
Save bartoleo/3392215d144130164a04 to your computer and use it in GitHub Desktop.
GFlappyAsciiBird v1.0 in one groovyscript
@Grapes(
@Grab(group='com.squidpony', module='squidlib', version='1.95.1')
)
import squidpony.squidgrid.gui.awt.event.SGMouseListener
import squidpony.squidgrid.gui.swing.SwingPane
import squidpony.squidcolor.SColor
import squidpony.squidcolor.SColorFactory
import javax.swing.*
import javax.swing.event.MouseInputListener
import java.awt.*
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import static java.awt.event.KeyEvent.VK_ESCAPE;
import static java.awt.event.KeyEvent.VK_UNDEFINED;
public class Pipe {
public double x
public int height
public int hole
public boolean scored = false
public String pipeStart = """\
[=======]"""
public String pipeMiddle = """\
| #|"""
int width = pipeStart.length()
}
public class Player {
public int x
public double y
public double dy
public String character = """\
_----.
C_ D(_o)
\\-___=="""
public int width = 8
public int height = 3
}
public enum GameState {
game,
gameOver,
menu;
}
class Game {
public static int DELAY = 1000 / 60
public static double GRAVITY = 0.035
public static double JUMP = -0.8
public static double SPEED = 0.25
public GameState state = GameState.game
public SwingPane display
public JFrame frame
public Renderer renderer
public Player player
public int score = 0
public ArrayList<Pipe> pipeList
public Game() {
// Setup window
// Generate map
renderer = new Renderer(RenderConfig.screenWidth, RenderConfig.screenHeight)
player = new Player()
player.x = 10
player.y = 10
player.dy = 0
pipeList = new ArrayList<>()
// set up display
frame = new JFrame("Groovy Flappy Ascii Bird")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLayout(new BorderLayout())
display = new SwingPane()
display.initialize(RenderConfig.screenWidth, RenderConfig.screenHeight, new Font("Ariel", Font.BOLD, 12))
clear(display)
frame.add(display, BorderLayout.SOUTH)
frame.setVisible(true)
frame.pack()
frame.setLocationRelativeTo(null)
frame.repaint()
frame.requestFocusInWindow()
CharacterInputListener dil = new CharacterInputListener(this, player)
int cellWidth = display.getCellDimension().width
int cellHeight = display.getCellDimension().height
MouseInputListener mil = new SGMouseListener(cellWidth, cellHeight, dil)
display.addMouseListener(mil) //listens for clicks and releases
display.addMouseMotionListener(mil) //listens for movement based events
frame.addKeyListener(dil)
render()
this.state = GameState.menu
javax.swing.Timer timer = new javax.swing.Timer(DELAY, new ActionListener() {
public void actionPerformed(ActionEvent event) {
stepSim();
}
});
timer.setRepeats(true);
timer.start();
}
public void render() {
clear(display)
renderer.render(display: display, game: this, player: player, pipeList: pipeList, score: score)
//render stats
//MessageLog.render(display, player)
//done rendering this frame
display.refresh();
}
public void clear(SwingPane display) {
for (int x = 0; x < RenderConfig.screenWidth; x++) {
for (int y = 0; y < RenderConfig.screenHeight; y++) {
display.clearCell(x, y)
}
}
display.refresh()
}
public void stepSim() {
if (this.state == GameState.game) {
player.dy += GRAVITY
player.y += player.dy
if (player.y + player.height >= RenderConfig.gameWindowY) {
this.state = GameState.gameOver
}
pipeList.each {
it.x -= SPEED
if (!it.scored && it.x < player.x) {
score++
it.scored = true
}
if (MathUtils.checkCollide(player.x, player.y as int, player.width, player.height, it.x as int, 0, it.width, it.height) ||
MathUtils.checkCollide(player.x, player.y as int, player.width, player.height, it.x as int, it.height + it.hole, it.width, RenderConfig.gameWindowY - it.height - it.hole)) {
this.state = GameState.gameOver
}
}
pipeList.removeAll {
it.x <= -it.width
}
if (pipeList.size() == 0 || (pipeList.size() == 1 && pipeList.get(0).x < RenderConfig.gameWindowX / 2)) {
Pipe pipe
pipe = new Pipe()
pipe.x = RenderConfig.gameWindowX
pipe.hole = MathUtils.getIntInRange(15, 30)
pipe.height = MathUtils.getIntInRange(1, RenderConfig.gameWindowY - pipe.hole - 1)
pipeList.add(pipe)
}
}
render()
}
public void jump() {
if (this.state == GameState.game) {
player.dy = JUMP
} else if (this.state == GameState.menu) {
this.state = GameState.game
}
}
public void escape() {
if (this.state == GameState.game) {
this.state = GameState.gameOver
}
}
}
class RenderConfig {
public static final int gameWindowX = 70
public static final int gameWindowY = 48
//total
public static final int screenWidth = 80
public static final int screenHeight = 50
}
class Renderer {
public int xSize
public int ySize
public Renderer(int x, int y) {
xSize = x
ySize = y
}
/**
* @param startx
* @param starty
*/
public void render(params) {
SwingPane display = params.display
Player player = params.player
ArrayList<Pipe> pipeList = params.pipeList
Integer score = params.score
int xRange = RenderConfig.gameWindowX
int yRange = RenderConfig.gameWindowY
xRange.times { x ->
display.placeCharacter(x, yRange, '-' as char, SColor.DARK_GRAY)
}
yRange.times { y ->
display.placeCharacter(xRange, y, '|' as char, SColor.DARK_GRAY)
}
display.placeCharacter(xRange, yRange, '+' as char, SColor.DARK_GRAY)
display.placeHorizontalString(xRange + 2, 2, "Score")
display.placeHorizontalString(xRange + 2, 4, score.toString())
xRange.times { i ->
display.placeCharacter(i, yRange-1, 'm' as char, SColor.GREEN)
}
int y = player.y
int x = player.x
player.character.eachLine {
y++
x = player.x
for (char ch : it.toCharArray()) {
x++
display.placeCharacter(x, y, ch, SColorFactory.asSColor(255, 255, 255));
}
}
pipeList.each {
String pipeString
for (int i = 1; i < yRange; i++) {
if (i < it.height || i > it.height + it.hole) {
pipeString = it.pipeMiddle
} else if (i == it.height || i == it.height + it.hole) {
pipeString = it.pipeStart
} else {
pipeString = ""
}
int px = it.x
for (char ch : pipeString.toCharArray()) {
px++
if (px > 0 && px < xRange) {
display.placeCharacter(px, i, ch, SColorFactory.asSColor(255, 255, 255));
}
}
}
}
if (params.game.state == GameState.gameOver) {
display.placeHorizontalString(xRange / 2 as int, yRange / 2 as int, "GAME OVER")
}
if (params.game.state == GameState.menu) {
display.placeHorizontalString((xRange / 2 - 16) as int, yRange / 2 as int, "Press a key or mouse button to start & jump")
}
}
}
/**
* A simple input listener.
*/
public class CharacterInputListener implements MouseInputListener, KeyListener {
Game context;
Player player;
public CharacterInputListener(Game context, Player player) {
this.context = context;
this.player = player;
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
context.jump();
}
@Override
public void mouseEntered(MouseEvent e) {
//nothing special happens
}
@Override
public void mouseExited(MouseEvent e) {
//nothing special happens
}
@Override
public void mouseDragged(MouseEvent e) {
// dragged = true;
}
@Override
public void mouseMoved(MouseEvent e) {
//nothing special happens
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
//http://forums.codeguru.com/showthread.php?495419-KeyListener-doesn-t-work-on-Windows-OS
handleKey(e);
}
@Override
public void keyReleased(KeyEvent e) {
}
private void handleKey(KeyEvent e) {
int code = e.getExtendedKeyCode();
// if ExtendedKeyCode is VK_UNDEFINED (0) use normal keycode
if (code == VK_UNDEFINED) {
code = e.getKeyCode();
}
boolean shift = e.isShiftDown();
switch (code) {
//movement
case VK_ESCAPE:
context.escape();
default:
context.jump();
break;
}
}
}
class MathUtils {
private static Random random
public static synchronized init() {
if (!random)
random = new Random()
}
/**
* @param low inclusive
* @param high inclusive
* @return
*/
public static int getIntInRange(int low, int high) {
if (low == high) return low
if (!random) init()
return random.nextInt(high + 1 - low) + low
}
public static boolean checkCollide(Integer x, Integer y, Integer oWidth, Integer oHeight, Integer xTwo, Integer yTwo, Integer oTwoWidth, Integer oTwoHeight) {
// AABB 1
int x1Min = x;
int x1Max = x + oWidth;
int y1Max = y + oHeight;
int y1Min = y;
// AABB 2
int x2Min = xTwo;
int x2Max = xTwo + oTwoWidth;
int y2Max = yTwo + oTwoHeight;
int y2Min = yTwo;
// Collision tests
if (x1Max < x2Min || x1Min > x2Max) return false;
if (y1Max < y2Min || y1Min > y2Max) return false;
return true;
}
}
Game game = new Game()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment