Merge pull request #3228 from open-osrs/revert-3226-revert-3224-delete-client
Some checks failed
OpenOSRS - CI (push) / Build (push) Has been cancelled
OpenOSRS - CI (push) / Test (push) Has been cancelled
OpenOSRS - CI (push) / Checkstyle main (push) Has been cancelled
OpenOSRS - CI (push) / Checkstyle test (push) Has been cancelled
OpenOSRS - Stale issues and PRs / stale (push) Has been cancelled
OpenOSRS - Scraper / scrape-npcs (push) Has been cancelled
OpenOSRS - Gradle Dependencies / update-wrapper (push) Has been cancelled
Some checks failed
OpenOSRS - CI (push) / Build (push) Has been cancelled
OpenOSRS - CI (push) / Test (push) Has been cancelled
OpenOSRS - CI (push) / Checkstyle main (push) Has been cancelled
OpenOSRS - CI (push) / Checkstyle test (push) Has been cancelled
OpenOSRS - Stale issues and PRs / stale (push) Has been cancelled
OpenOSRS - Scraper / scrape-npcs (push) Has been cancelled
OpenOSRS - Gradle Dependencies / update-wrapper (push) Has been cancelled
client: snake is back on the menu boys
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
package com.thatgamerblue.snake;
|
||||||
|
|
||||||
|
public enum Direction {
|
||||||
|
UP(0, -1, "^"),
|
||||||
|
DOWN(0, 1, "v"),
|
||||||
|
LEFT(-1, 0, "<"),
|
||||||
|
RIGHT(1, 0, ">");
|
||||||
|
|
||||||
|
public int xOffset;
|
||||||
|
public int yOffset;
|
||||||
|
public String display;
|
||||||
|
|
||||||
|
Direction(int xOff, int yOff, String display) {
|
||||||
|
xOffset = xOff;
|
||||||
|
yOffset = yOff;
|
||||||
|
this.display = display;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package com.thatgamerblue.snake;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
public class GameHandler implements KeyListener {
|
||||||
|
private static final int DEFAULT_REFRESH_INTERVAL = 100;
|
||||||
|
private static final int PX_PER_TILE = 16;
|
||||||
|
private static final int WIDTH = SnakeGame.FRAME_WIDTH / PX_PER_TILE;
|
||||||
|
private static final int HEIGHT = SnakeGame.FRAME_HEIGHT / PX_PER_TILE;
|
||||||
|
private static final int MIDDLE_X = WIDTH / 2;
|
||||||
|
private static final int MIDDLE_Y = HEIGHT / 2;
|
||||||
|
private static final Color SNAKE_HEAD_COLOR = Color.GREEN;
|
||||||
|
private static final Color SNAKE_BODY_COLOR = new Color(0, 128, 0);
|
||||||
|
private static final Color APPLE_COLOR = Color.RED;
|
||||||
|
private static final Font HEAD_FONT = new Font("Arial", Font.BOLD, 12);
|
||||||
|
private static final Font FONT = new Font("Arial", Font.BOLD, 16);
|
||||||
|
|
||||||
|
private final Set<Integer> keysPressed = new HashSet<>();
|
||||||
|
private Direction pendingDirection = Direction.LEFT;
|
||||||
|
private Direction direction = Direction.LEFT;
|
||||||
|
private SnakePart head;
|
||||||
|
private SnakePart apple = new SnakePart();
|
||||||
|
private int score;
|
||||||
|
|
||||||
|
private SnakeGame game;
|
||||||
|
|
||||||
|
public GameHandler(SnakeGame game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
if (score != 0) {
|
||||||
|
JOptionPane.showMessageDialog(null, "You died! Your score: " + score, "OpenOSRS Snake", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
head = new SnakePart();
|
||||||
|
SnakePart current = head;
|
||||||
|
current.x = MIDDLE_X;
|
||||||
|
current.y = MIDDLE_Y;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
current.next = new SnakePart();
|
||||||
|
current = current.next;
|
||||||
|
current.x = MIDDLE_X + i + 1;
|
||||||
|
current.y = MIDDLE_Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
direction = Direction.LEFT;
|
||||||
|
pendingDirection = Direction.LEFT;
|
||||||
|
createNewApple();
|
||||||
|
score = 0;
|
||||||
|
SnakeGame.currentRefreshInterval = DEFAULT_REFRESH_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() throws Exception {
|
||||||
|
processInput();
|
||||||
|
direction = pendingDirection;
|
||||||
|
SnakePart newHead = new SnakePart();
|
||||||
|
newHead.x = head.x + direction.xOffset;
|
||||||
|
newHead.y = head.y + direction.yOffset;
|
||||||
|
newHead.next = head;
|
||||||
|
head = newHead;
|
||||||
|
|
||||||
|
boolean ateApple = false;
|
||||||
|
if (head.x == apple.x && head.y == apple.y) {
|
||||||
|
createNewApple();
|
||||||
|
ateApple = true;
|
||||||
|
score++;
|
||||||
|
SnakeGame.currentRefreshInterval = Math.max(50, DEFAULT_REFRESH_INTERVAL - score);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ateApple) {
|
||||||
|
SnakePart current = head;
|
||||||
|
while (current.next.next != null) {
|
||||||
|
current = current.next;
|
||||||
|
}
|
||||||
|
current.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT) {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
SnakePart current = head.next;
|
||||||
|
while (current.next != null) {
|
||||||
|
if (current.x == head.x && current.y == head.y) {
|
||||||
|
reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = current.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point findAppleSpawn() {
|
||||||
|
Set<Point> used = new HashSet<>();
|
||||||
|
for (SnakePart part = head; part != null; part = part.next) {
|
||||||
|
used.add(new Point(part.x, part.y));
|
||||||
|
}
|
||||||
|
int x, y;
|
||||||
|
do {
|
||||||
|
x = (int) (Math.random() * (WIDTH - 2)) + 1;
|
||||||
|
y = (int) (Math.random() * (HEIGHT - 2)) + 1;
|
||||||
|
} while (used.contains(new Point(x, y)));
|
||||||
|
return new Point(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createNewApple() {
|
||||||
|
Point spawn = findAppleSpawn();
|
||||||
|
apple.x = spawn.x;
|
||||||
|
apple.y = spawn.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processInput() {
|
||||||
|
if (keysPressed.contains(KeyEvent.VK_UP)) {
|
||||||
|
if (direction != Direction.DOWN) {
|
||||||
|
pendingDirection = Direction.UP;
|
||||||
|
}
|
||||||
|
} else if (keysPressed.contains(KeyEvent.VK_DOWN)) {
|
||||||
|
if (direction != Direction.UP) {
|
||||||
|
pendingDirection = Direction.DOWN;
|
||||||
|
}
|
||||||
|
} else if (keysPressed.contains(KeyEvent.VK_LEFT)) {
|
||||||
|
if (direction != Direction.RIGHT) {
|
||||||
|
pendingDirection = Direction.LEFT;
|
||||||
|
}
|
||||||
|
} else if (keysPressed.contains(KeyEvent.VK_RIGHT)) {
|
||||||
|
if (direction != Direction.LEFT) {
|
||||||
|
pendingDirection = Direction.RIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void draw(Graphics g) {
|
||||||
|
// draw snake head
|
||||||
|
g.setColor(SNAKE_HEAD_COLOR);
|
||||||
|
SnakePart current = head;
|
||||||
|
while (current != null) {
|
||||||
|
g.fillRect(current.x * PX_PER_TILE, current.y * PX_PER_TILE, PX_PER_TILE, PX_PER_TILE);
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.drawRect(current.x * PX_PER_TILE, current.y * PX_PER_TILE, PX_PER_TILE, PX_PER_TILE);
|
||||||
|
if (current == head) {
|
||||||
|
g.setFont(HEAD_FONT);
|
||||||
|
g.drawString(direction.display, head.x * PX_PER_TILE + 6, (head.y + 1) * PX_PER_TILE - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current.next;
|
||||||
|
g.setColor(SNAKE_BODY_COLOR);
|
||||||
|
}
|
||||||
|
g.setColor(APPLE_COLOR);
|
||||||
|
g.fillRect(apple.x * PX_PER_TILE, apple.y * PX_PER_TILE, PX_PER_TILE, PX_PER_TILE);
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.drawRect(apple.x * PX_PER_TILE, apple.y * PX_PER_TILE, PX_PER_TILE, PX_PER_TILE);
|
||||||
|
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.setFont(FONT);
|
||||||
|
g.drawString("Score: " + score, SnakeGame.FRAME_WIDTH - 100, SnakeGame.FRAME_HEIGHT - 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
keysPressed.add(e.getKeyCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
keysPressed.remove(e.getKeyCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
package com.thatgamerblue.snake;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Image;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
|
||||||
|
public class SnakeGame {
|
||||||
|
public static String[] arguments;
|
||||||
|
public static final int FRAME_WIDTH = 800;
|
||||||
|
public static final int FRAME_HEIGHT = 608;
|
||||||
|
public static long currentRefreshInterval = 100;
|
||||||
|
private static GameHandler gameHandler;
|
||||||
|
private final Object redrawLock = new Object();
|
||||||
|
private Component component;
|
||||||
|
private Image imageBuffer;
|
||||||
|
private boolean running = true;
|
||||||
|
|
||||||
|
public void start(Component component) {
|
||||||
|
this.component = component;
|
||||||
|
gameHandler.reset();
|
||||||
|
imageBuffer = component.createImage(component.getWidth(),
|
||||||
|
component.getHeight());
|
||||||
|
Thread thread = new Thread(this::runGameLoop);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() throws Exception {
|
||||||
|
int option = JOptionPane.showConfirmDialog(null,
|
||||||
|
"You scored 15! Press Yes to launch OpenOSRS, press No to keep playing snake.",
|
||||||
|
"OpenOSRS Snake", JOptionPane.YES_NO_OPTION);
|
||||||
|
if (option == JOptionPane.YES_OPTION) {
|
||||||
|
running = false;
|
||||||
|
Component c = component;
|
||||||
|
while (c != null) {
|
||||||
|
c.setVisible(false);
|
||||||
|
c = c.getParent();
|
||||||
|
}
|
||||||
|
RuneLite.oldMain(arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private void runGameLoop() {
|
||||||
|
// update the game repeatedly
|
||||||
|
while (running) {
|
||||||
|
long durationMs = redraw();
|
||||||
|
try {
|
||||||
|
Thread.sleep(Math.max(0, currentRefreshInterval - durationMs));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long redraw() throws Exception {
|
||||||
|
|
||||||
|
long t = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// At this point perform changes to the model that the component will
|
||||||
|
// redraw
|
||||||
|
|
||||||
|
updateModel();
|
||||||
|
|
||||||
|
// draw the model state to a buffered image which will get
|
||||||
|
// painted by component.paint().
|
||||||
|
drawModelToImageBuffer();
|
||||||
|
|
||||||
|
// asynchronously signals the paint to happen in the awt event
|
||||||
|
// dispatcher thread
|
||||||
|
component.repaint();
|
||||||
|
|
||||||
|
// use a lock here that is only released once the paintComponent
|
||||||
|
// has happened so that we know exactly when the paint was completed and
|
||||||
|
// thus know how long to pause till the next redraw.
|
||||||
|
waitForPaint();
|
||||||
|
|
||||||
|
// return time taken to do redraw in ms
|
||||||
|
return System.currentTimeMillis() - t;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateModel() throws Exception {
|
||||||
|
gameHandler.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawModelToImageBuffer() {
|
||||||
|
drawModel(imageBuffer.getGraphics());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawModel(Graphics g) {
|
||||||
|
g.setColor(component.getBackground());
|
||||||
|
g.fillRect(0, 0, component.getWidth(), component.getHeight());
|
||||||
|
g.setColor(component.getForeground());
|
||||||
|
gameHandler.draw(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitForPaint() {
|
||||||
|
try {
|
||||||
|
synchronized (redrawLock) {
|
||||||
|
redrawLock.wait();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resume() {
|
||||||
|
synchronized (redrawLock) {
|
||||||
|
redrawLock.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
// paint the buffered image to the graphics
|
||||||
|
g.drawImage(imageBuffer, 0, 0, component);
|
||||||
|
|
||||||
|
// resume the game loop
|
||||||
|
resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SnakeComponent extends JPanel {
|
||||||
|
|
||||||
|
private final SnakeGame game;
|
||||||
|
|
||||||
|
public SnakeComponent(SnakeGame game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
game.paint(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
arguments = args;
|
||||||
|
java.awt.EventQueue.invokeLater(() -> {
|
||||||
|
SnakeGame game = new SnakeGame();
|
||||||
|
SnakeComponent component = new SnakeComponent(game);
|
||||||
|
|
||||||
|
gameHandler = new GameHandler(game);
|
||||||
|
|
||||||
|
component.setPreferredSize(new java.awt.Dimension(FRAME_WIDTH, FRAME_HEIGHT));
|
||||||
|
JFrame frame = new JFrame();
|
||||||
|
|
||||||
|
frame.setTitle("OpenOSRS Snake");
|
||||||
|
frame.setResizable(false);
|
||||||
|
|
||||||
|
frame.addKeyListener(gameHandler);
|
||||||
|
frame.setFocusable(true);
|
||||||
|
frame.setFocusTraversalKeysEnabled(false);
|
||||||
|
|
||||||
|
frame.setLayout(new BorderLayout());
|
||||||
|
frame.getContentPane().add(component, BorderLayout.CENTER);
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setVisible(true);
|
||||||
|
frame.pack();
|
||||||
|
|
||||||
|
game.start(component);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.thatgamerblue.snake;
|
||||||
|
|
||||||
|
public class SnakePart {
|
||||||
|
public SnakePart next;
|
||||||
|
int x, y;
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ import com.google.inject.Injector;
|
|||||||
import com.openosrs.client.OpenOSRS;
|
import com.openosrs.client.OpenOSRS;
|
||||||
import com.openosrs.client.game.PlayerManager;
|
import com.openosrs.client.game.PlayerManager;
|
||||||
import com.openosrs.client.ui.OpenOSRSSplashScreen;
|
import com.openosrs.client.ui.OpenOSRSSplashScreen;
|
||||||
|
import com.thatgamerblue.snake.SnakeGame;
|
||||||
import java.applet.Applet;
|
import java.applet.Applet;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -48,6 +49,7 @@ import java.security.KeyManagementException;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -59,6 +61,7 @@ import javax.inject.Singleton;
|
|||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||||
import joptsimple.OptionParser;
|
import joptsimple.OptionParser;
|
||||||
@@ -95,6 +98,7 @@ import okhttp3.Cache;
|
|||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -174,8 +178,15 @@ public class RuneLite
|
|||||||
@Nullable
|
@Nullable
|
||||||
private RuntimeConfig runtimeConfig;
|
private RuntimeConfig runtimeConfig;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception
|
private static final String BYPASS_ARG = "--IWillNotComplainIfIGetSentToTheGulagByJamflex";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
SnakeGame.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void oldMain(String[] args) throws Exception
|
||||||
{
|
{
|
||||||
|
args = Arrays.stream(args).filter(s -> !BYPASS_ARG.equals(s)).toArray(String[]::new);
|
||||||
Locale.setDefault(Locale.ENGLISH);
|
Locale.setDefault(Locale.ENGLISH);
|
||||||
|
|
||||||
final OptionParser parser = new OptionParser(false);
|
final OptionParser parser = new OptionParser(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user