в основном я играю в многопользовательскую игру-змею для проекта хобб ie, но я просто застрял на этом белом экране (потому что графика ничего не рисует) в течение месяца. Я пытался реорганизовать код, используя код без метода рисования, просто бесконечно, а потом я просто испугался, есть какие-нибудь идеи? Главный клиент
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
Gameplay gameplay = new Gameplay();
frame.setBounds(10, 10, 905, 700);
frame.setBackground(Color.DARK_GRAY);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(gameplay);
}
}
Клиентский игровой процесс
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Objects;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Gameplay extends JPanel implements KeyListener, ActionListener, Serializable{
private static final long serialVersionUID = 1L;
Socket socket;
private int[] snakeXLength = new int[750];
private int[] snakeYLength = new int[750];
private boolean left = false;
private boolean right = false;
private boolean up = false;
private boolean down = false;
ArrayList<Boolean> arrows = new ArrayList<Boolean>() {
private static final long serialVersionUID = 1L;
{
add(left);
add(right);
add(up);
add(down);
}
};
private int snakeLength = 3;
private boolean dead = false;
int keyCode;
private Timer timer;
private int delay = 100;
private ImageIcon bodyImage;
private int[] foodXPosList = {25,50,75,100,125,150,175,200,225,250,275,300,325,
350,375,400,425,450,475,500,525,550,575,600,625,650,675,700,725,750,
775,800,825,850};
private int[] foodYPosList = {75,100,125,150,175,200,225,250,275,300,325,
350,375,400,425,450,475,500,525,550,575,600,625};
private ImageIcon foodImage;
private boolean started = false;
private int deads = 0;
private int moves = 0;
private ImageIcon titleImage;
private int playersConnected;
ObjectInputStream receive;
ObjectOutputStream send;
Server.ClientVariables server;
public Gameplay() {
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer = new Timer (delay, this);
timer.start();
try{
socket = new Socket("127.0.0.1", 666);
}catch(UnknownHostException ex1){
System.out.println("Server unknown");
System.exit(1);
}catch(IOException ex2){
System.out.println("Error starting the server");
System.exit(1);
}
}
public class ServerVariables {
boolean dead = false;
int snakeLength;
int[] snakeXLength = new int[750];
int[] snakeYLength = new int[750];
ArrayList<Boolean> arrows;
}
public void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ServerVariables serverVariables = new ServerVariables();
public void paint (Graphics graphics) {
try {
receive = Objects.requireNonNull(new ObjectInputStream(receive));
server = Objects.requireNonNull((Server.ClientVariables) receive.readObject());
send = Objects.requireNonNull(new ObjectOutputStream(socket.getOutputStream()));
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//image border
graphics.setColor(Color.WHITE);
graphics.drawRect(24, 10, 851, 55);
//title image
titleImage = new ImageIcon("assets/snaketitle.jpg");
titleImage.paintIcon(this, graphics, 25, 11);
//border of gameplay
graphics.setColor(Color.WHITE);
graphics.drawRect(24, 74, 851, 577);
//background
graphics.setColor(Color.BLACK);
graphics.fillRect(25, 75, 850, 575);
//score
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.PLAIN, 14));
graphics.drawString("Score: " + (server.snake[server.id].snakeLength - 2), 780, 30);
//Length of snake text
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.PLAIN, 14));
graphics.drawString("Length: " + snakeLength, 780, 50);
//snake
//array of all mouth image objects
ImageIcon[] mouth = {
new ImageIcon("assets/leftMouth.png"),
new ImageIcon("assets/rightMouth.png"),
new ImageIcon("assets/upMouth.png"),
new ImageIcon("assets/downMouth.png")
};
ImageIcon[] enemyMouth = {
new ImageIcon("assets/leftMouth_black.png"),
new ImageIcon("assets/rightMouth_black.png"),
new ImageIcon("assets/upMouth_black.png"),
new ImageIcon("assets/downMouth_black.png")
};
//the starting snake size
if (moves == 0) {
//the starting mouth position
mouth[1].paintIcon(this, graphics, snakeXLength[0], snakeYLength[0]);
//starting position
snakeXLength [0] = 100;
snakeXLength [1] = 75;
snakeXLength [2] = 50;
switch(server.id) {
case 0:
snakeYLength [0] = 100;
snakeYLength [1] = 100;
snakeYLength [2] = 100;
case 1:
snakeYLength [0] = 200;
snakeYLength [1] = 200;
snakeYLength [2] = 200;
case 2:
snakeYLength [0] = 300;
snakeYLength [1] = 300;
snakeYLength [2] = 300;
case 3:
snakeYLength [0] = 400;
snakeYLength [1] = 400;
snakeYLength [2] = 400;
}
}
else {
snakeXLength = server.snake[server.id].snakeXLength;
snakeYLength = server.snake[server.id].snakeYLength;
snakeLength = server.snake[server.id].snakeLength;
}
//changing the mouth according to the pressed key and creating the snake
for(int i=0; i<snakeLength; i++) {
if (i==0) {
for(int a=0; a<arrows.size(); a++) {
if (arrows.get(a)) {
mouth[a].paintIcon(this, graphics, snakeXLength[i], snakeYLength[i]);
}
}
}
else {
bodyImage = new ImageIcon("assets/bodyImage.png");
bodyImage.paintIcon(this, graphics, snakeXLength[i], snakeYLength[i]);
}
}
//win
deads = 0;
for (int i=0; i<=3; i++) {
if(i == server.id) {
return;
}
else {
if (server.snake[i].dead) {
deads+=1;
}
}
}
if (deads == 3) {
if (!server.snake[server.id].dead) {
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.BOLD, 50));
graphics.drawString("VICTORY", 300, 300);
graphics.drawString("Your score was " + (server.snake[server.id].snakeLength - 2), 300, 340);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
serverVariables.dead = true;
send.writeObject(serverVariables);
send.flush();
System.exit(0);
} catch (IOException e) {
System.out.println("Error closing the server");
System.exit(0);
}
}
}
//snake collision
for(int i=1; i<snakeLength; i++) {
if(snakeXLength[i] == snakeXLength[0] && snakeYLength[i] == snakeYLength[0]) {
for(int a=0; a<arrows.size(); a++) {
arrows.set(a, false);
}
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.BOLD, 50));
graphics.drawString("Game Over", 300, 300);
graphics.drawString("Your score was " + (server.snake[server.id].snakeLength - 2), 300, 340);
graphics.setFont(new Font("arial", Font.BOLD, 20));
graphics.drawString("Space to Exit", 400, 380);
dead = true;
try {
serverVariables.dead = true;
for (int a = 0; a<4; a++) {
if(serverVariables.arrows.get(i)) {
serverVariables.arrows.set(i, false);
}
}
send.writeObject(serverVariables);
send.flush();
} catch (IOException e) {
System.out.println("Error sending snake data to server");
}
}
}
//Dead
if (server.snake[server.id].dead) {
for(int a=0; a<arrows.size(); a++) {
arrows.set(a, false);
}
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.BOLD, 50));
graphics.drawString("Game Over", 300, 300);
graphics.setFont(new Font("arial", Font.BOLD, 20));
graphics.drawString("Score: " + (server.snake[server.id].snakeLength - 2), 350, 340);
sleep(5);
System.exit(0);
}
//food
foodImage = new ImageIcon("assets/food.png");
for (int i = 0;i<server.food.length;i++) {
foodImage.paintIcon(this, graphics, foodXPosList[server.food[i].foodXPos], foodYPosList[server.food[i].foodYPos]);
}
//waiting room
if (server.started == false) {
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.BOLD, 50));
playersConnected = 4;
for (Server.Snake snake : server.snake) {
if (snake.snakeXLength[0] != 100) {
playersConnected-=1;
}
}
graphics.drawString("Waiting for players to connect: " + playersConnected + "/4", 200, 200);
}
else if(!started){
graphics.setColor(Color.WHITE);
graphics.setFont(new Font("arial", Font.BOLD, 100));
graphics.drawString("3", 430, 350);
sleep(1000);
graphics.drawString("2", 430, 350);
sleep(1000);
graphics.drawString("1", 430, 350);
sleep(1000);
graphics.drawString("GO", 420, 350);
arrows.set(1, true);
started = true;
}
if(server.started) {
for (Server.Snake snake : server.snake) {
if (snake == server.snake[server.id]) {
continue;
}
else if (snake.dead == false) {
if (moves == 0) {
//the starting mouth position
enemyMouth[1].paintIcon(this, graphics, snake.snakeXLength[0], snake.snakeYLength[0]);
//starting position
snake.snakeXLength [0] = 100;
snake.snakeXLength [1] = 75;
snake.snakeXLength [2] = 50;
switch(snake.id) {
case 0:
snake.snakeYLength [0] = 100;
snake.snakeYLength [1] = 100;
snake.snakeYLength [2] = 100;
case 1:
snake.snakeYLength [0] = 200;
snake.snakeYLength [1] = 200;
snake.snakeYLength [2] = 200;
case 2:
snake.snakeYLength [0] = 300;
snake.snakeYLength [1] = 300;
snake.snakeYLength [2] = 300;
case 3:
snake.snakeYLength [0] = 400;
snake.snakeYLength [1] = 400;
snake.snakeYLength [2] = 400;
}
}
//changing the mouth according to the pressed key and creating the snake
for(int i=0; i<snake.snakeLength; i++) {
if (i==0) {
for(int a=0; a<snake.arrows.size(); a++) {
if (snake.arrows.get(a)) {
enemyMouth[a].paintIcon(this, graphics, snake.snakeXLength[0], snake.snakeYLength[0]);
}
}
}
else {
bodyImage = new ImageIcon("assets/bodyImage_black.png");
bodyImage.paintIcon(this, graphics, snake.snakeXLength[i], snake.snakeYLength[i]);
}
}
}
}
}
graphics.dispose();
}
@Override
public void actionPerformed(ActionEvent arg0) {
timer.start();
if(arrows.get(0)) {
for(int a=snakeLength-1; a>=0; a--) {
snakeYLength[a+1] = snakeYLength[a];
}
for(int a=snakeLength; a>=0; a--) {
if (a==0) {
snakeXLength[a] = snakeXLength[a] - 25;
}
else {
snakeXLength[a] = snakeXLength[a-1];
}
if (snakeXLength[a] < 25) {
snakeXLength[a] = 850;
}
}
try {
ObjectOutputStream send = new ObjectOutputStream(socket.getOutputStream());
serverVariables.snakeXLength = snakeXLength;
serverVariables.snakeYLength = snakeYLength;
serverVariables.snakeLength = snakeLength;
serverVariables.arrows = arrows;
send.writeObject(serverVariables);
send.flush();
} catch (IOException e) {
System.out.println("Error sending snake data to server");
}
//run the paint() method again
repaint();
}
else if(arrows.get(1)) {
for(int a=snakeLength-1; a>=0; a--) {
snakeYLength[a+1] = snakeYLength[a];
}
for(int a=snakeLength; a>=0; a--) {
if (a==0) {
snakeXLength[a] = snakeXLength[a] + 25;
}
else {
snakeXLength[a] = snakeXLength[a-1];
}
if (snakeXLength[a] > 850) {
snakeXLength[a] = 25;
}
}
try {
ObjectOutputStream send = new ObjectOutputStream(socket.getOutputStream());
serverVariables.snakeXLength = snakeXLength;
serverVariables.snakeYLength = snakeYLength;
serverVariables.snakeLength = snakeLength;
serverVariables.arrows = arrows;
send.writeObject(serverVariables);
send.flush();
} catch (IOException e) {
System.out.println("Error sending snake data to server");
}
//run the paint() method again
repaint();
}
else if(arrows.get(2)) {
for(int a=snakeLength-1; a>=0; a--) {
snakeXLength[a+1] = snakeXLength[a];
}
for(int a=snakeLength; a>=0; a--) {
if (a==0) {
snakeYLength[a] = snakeYLength[a] - 25;
}
else {
snakeYLength[a] = snakeYLength[a-1];
}
if (snakeYLength[a] < 75) {
snakeYLength[a] = 625;
}
}
try {
ObjectOutputStream send = new ObjectOutputStream(socket.getOutputStream());
serverVariables.snakeXLength = snakeXLength;
serverVariables.snakeYLength = snakeYLength;
serverVariables.snakeLength = snakeLength;
serverVariables.arrows = arrows;
send.writeObject(serverVariables);
send.flush();
} catch (IOException e) {
System.out.println("Error sending snake data to server");
}
//run the paint() method again
repaint();
}
else if(arrows.get(3)) {
for(int a=snakeLength-1; a>=0; a--) {
snakeXLength[a+1] = snakeXLength[a];
}
for(int a=snakeLength; a>=0; a--) {
if (a==0) {
snakeYLength[a] = snakeYLength[a] + 25;
}
else {
snakeYLength[a] = snakeYLength[a-1];
}
if (snakeYLength[a] > 625) {
snakeYLength[a] = 75;
}
}
try {
ObjectOutputStream send = new ObjectOutputStream(socket.getOutputStream());
serverVariables.snakeXLength = snakeXLength;
serverVariables.snakeYLength = snakeYLength;
serverVariables.snakeLength = snakeLength;
serverVariables.arrows = arrows;
send.writeObject(serverVariables);
send.flush();
} catch (IOException e) {
System.out.println("Error sending snake data to server");
}
//run the paint() method again
repaint();
}
}
@Override
public void keyPressed(KeyEvent e) {
keyCode = e.getKeyCode();
if (server.started) {
if (dead) {
//space
if (keyCode == KeyEvent.VK_SPACE) {
System.exit(1);
}
}
else {
switch( keyCode ) {
//arrows
case KeyEvent.VK_LEFT:
if(!arrows.get(1)) {
arrows.set(0, true);
arrows.set(3, false);
arrows.set(2, false);
moves++;
}
break;
case KeyEvent.VK_RIGHT :
if(!arrows.get(0)) {
arrows.set(1, true);
arrows.set(3, false);
arrows.set(2, false);
moves++;
}
break;
case KeyEvent.VK_UP:
if(!arrows.get(3)) {
arrows.set(2, true);
arrows.set(1, false);
arrows.set(0, false);
moves++;
}
break;
case KeyEvent.VK_DOWN:
if(!arrows.get(2)) {
arrows.set(3, true);
arrows.set(1, false);
arrows.set(0, false);
moves++;
}
break;
//WASD
case KeyEvent.VK_A:
if(!arrows.get(1)) {
arrows.set(0, true);
arrows.set(3, false);
arrows.set(2, false);
moves++;
}
break;
case KeyEvent.VK_D :
if(!arrows.get(0)) {
arrows.set(1, true);
arrows.set(3, false);
arrows.set(2, false);
moves++;
}
break;
case KeyEvent.VK_W:
if(!arrows.get(3)) {
arrows.set(2, true);
arrows.set(1, false);
arrows.set(0, false);
moves++;
}
break;
case KeyEvent.VK_S:
if(!arrows.get(2)) {
arrows.set(3, true);
arrows.set(1, false);
arrows.set(0, false);
moves++;
}
break;
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
Сервер
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Random;
public class Server {
Random random = new Random();
Food initialFoods = new Food() {
{
foodXPos = random.nextInt(34);
foodYPos = random.nextInt(23);
}
};
//se só aparecer 1 fruta ou der erro criar mais 1 objeto Food
Food[] food = {initialFoods, initialFoods};
Snake[] snake = {};
ArrayList<Snake> usedSnakes;
final int port= 666;
ServerSocket server;
int id = 0;
int usersConnected = 0;
public Server() {
startServer();
}
public class ClientVariables {
int id;
Snake[] snake;
Food[] food;
boolean started;
}
public class Snake {
int id;
boolean dead = false;
int snakeLength;
int[] snakeXLength = new int[750];
int[] snakeYLength = new int[750];
ArrayList<Boolean> arrows = new ArrayList<Boolean>();
}
public class Food {
int foodXPos = random.nextInt(34);
int foodYPos = random.nextInt(23);
}
public void transformVariables (Gameplay.ServerVariables in, int id) {
snake[id].dead = in.dead;
snake[id].snakeLength = in.snakeLength;
snake[id].snakeXLength = in.snakeXLength;
snake[id].snakeYLength = in.snakeYLength;
snake[id].arrows = in.arrows;
}
private void startServer() {
try {
server = new ServerSocket(port);
while(id<4){
System.out.println("Waiting for clients to connect");
Socket client = server.accept();
System.out.println("Client connected ");
ClientThread clientThread = new ClientThread(client, id);
clientThread.start();
id+=1;
usersConnected+=1;
}
}catch(IOException ex){
System.out.println("Error starting the server");
System.exit(1);
}
}
class ClientThread extends Thread{
ClientVariables clientVariables = new ClientVariables();
Gameplay.ServerVariables read;
ObjectOutputStream out;
ObjectInputStream in;
Socket client;
InputStream inputStream;
int deads;
int id;
public ClientThread(Socket client, int id) {
this.client = client;
this.id = id;
try{
inputStream = client.getInputStream();
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(inputStream);
}catch(IOException ex){
System.out.println("Client Disconnected");
}
}
public void run() {
try {
while (true) {
read = (Gameplay.ServerVariables) in.readObject();
if (read.dead) {
snake[id].dead = true;
break;
}
transformVariables(read, id);
//check for game finished
deads = 0;
for (Snake snake : snake) {
if (snake.dead) {
snake.dead = true;
break;
}
}
if (deads == 4) {
System.out.println("Game finished");
System.exit(1);
}
//check for collisions(food or snakes)
usedSnakes = new ArrayList<Snake>();
for (Snake firstSnake : snake) {
for (Food food : food) {
if (firstSnake.snakeXLength[0] == food.foodXPos && firstSnake.snakeYLength[0] == food.foodYPos) {
firstSnake.snakeLength+=1;
food.foodXPos = random.nextInt(34);
food.foodYPos = random.nextInt(23);
}
}
for (Snake otherSnake : snake) {
if (firstSnake == otherSnake) {
continue;
}
for (Snake singleSnake : usedSnakes) {
if (otherSnake == singleSnake) {
continue;
}
}
for (int bodyPart : otherSnake.snakeXLength) {
if (firstSnake.snakeXLength[0] == bodyPart) {
if (bodyPart == otherSnake.snakeXLength[0]) {
snake[firstSnake.id].dead = true;
snake[otherSnake.id].dead = true;
}
else {
snake[firstSnake.id].dead = true;
}
}
}
}
}
//Sending the data back to the client
//server variables
clientVariables.id = id;
clientVariables.snake = snake;
clientVariables.food = food;
if (usersConnected == 4) {
clientVariables.started = true;
}
else {
clientVariables.started = false;
}
out.writeObject(clientVariables);
out.flush();
}
}
catch(SocketException e) {
try {
out.close();
in.close();
client.close();
System.out.println("Error3");
System.out.println("Client disconnected");
} catch (IOException e1) {
System.out.println("Error2");
e1.printStackTrace();
}
}catch(IOException ex) {
System.out.println("Error1");
System.out.println("Client disconnected");
}catch (ClassNotFoundException e) {
System.out.println("Error0");
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server();
}
}