Proje Fun Project: Snake Minigame

  • Konuyu Başlatan Konuyu Başlatan Senpai
  • Başlangıç tarihi Başlangıç tarihi
  • Görüntüleme 393
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...

Senpai

Züm... Zümrü... Zümrüt...
Yasaklandı
Katılım
24 Kasım 2014
Mesajlar
816
Elmaslar
341
Puan
14.845
Yaş
27
Konum
Istanbul
Minecraft
NaN2
Hem eğlenceli olacağını düşündüğüm için hem de biraz elimi alıştırmak için bu sabah yaptığım bir proje.

Aklımda son 1-2 özellik daha var bittiği zaman açık kaynak olarak paylaşacağım zaten.

Özellikler:

- Snake oyununun mekaniği hatasız bir şekilde uyarlandı.
- Kozmetik sistemi (snake skin, boosters, trails vb)
- Powerups (Oyun ekranında rastgele beliren powerupları aldığınızda 10saniyelik özel bir güç kazanıyorsunuz, Ghost Mode, Immune, Speed vs vs)




Screenshot 2025-04-01 at 16.44.06.webp

Screenshot 2025-04-01 at 16.44.18.webp

Screenshot 2025-04-01 at 16.44.22.webp

Screenshot 2025-04-01 at 16.44.45.webp


Tamamen eğlence için yapılan bir proje, muhtemelen dünyada kimsenin işine yaramayacaktır :D
 
proof of ownership:
1743515952044.webp
 
eline sağlık gui games'ten sonra bu ilaç gibi geldi xd. tuş algılama methodunu az açsaydın keşke :( (çalmak için xd) bence oyun sistemini display text'e taşıyabilirsin, kullanım alanı daha uygun sanki; yurt dışında adamlar animasyonlu billboard fln yapıyor
 
eline sağlık gui games'ten sonra bu ilaç gibi geldi xd. tuş algılama methodunu az açsaydın keşke :( (çalmak için xd) bence oyun sistemini display text'e taşıyabilirsin, kullanım alanı daha uygun sanki; yurt dışında adamlar animasyonlu billboard fln yapıyor
Kod:
package net.hywave.snake.listeners;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerAction;

import org.bukkit.entity.Player;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.GameMode;

import net.hywave.snake.Engine;
import net.hywave.snake.model.Direction;
import net.hywave.snake.model.GameSession;
import net.hywave.snake.state.PlayerState;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class KeyHandler implements Listener {
    private final Engine plugin;
    private final ProtocolManager protocolManager;

    private final Map<UUID, Long> lastDirectionChange = new ConcurrentHashMap<>();
    private final Map<UUID, Direction> lastDirection = new ConcurrentHashMap<>();
   
    // cache merge [w,a,s,d]
    private final Map<UUID, Boolean> pressedW = new ConcurrentHashMap<>();
    private final Map<UUID, Boolean> pressedA = new ConcurrentHashMap<>();
    private final Map<UUID, Boolean> pressedS = new ConcurrentHashMap<>();
    private final Map<UUID, Boolean> pressedD = new ConcurrentHashMap<>();
   
    private final boolean DEBUG_MODE = false;
    private static final long COOLDOWN_MS = 50; // Comment<[email protected]>: Please don't change this
   
    public KeyHandler(Engine plugin) {
        this.plugin = plugin;
        this.protocolManager = ProtocolLibrary.getProtocolManager();
       
        Bukkit.getPluginManager().registerEvents(this, plugin);
        registerKeyListeners();
        plugin.getLogger().info("dbg: done binding kb packets in " + COOLDOWN_MS + "ms");
       
        if (DEBUG_MODE) { startDebugTask(); }
    }
   
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        resetKeyState(player.getUniqueId());
       
        if (DEBUG_MODE) {
            Bukkit.getScheduler().runTaskLater(plugin, () -> {
                player.sendMessage(ChatColor.GREEN + "dbg: please test & report key handling performance");
            }, 40L);
        }
    }
   
    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent event) {
        Player player = event.getPlayer();
        resetKeyState(player.getUniqueId());
    }
   
    // FOR TESTING PURPOSES, DON'T REMOVE THIS
    @EventHandler
    public void onPlayerToggleSprint(PlayerToggleSprintEvent event) {
        Player player = event.getPlayer();
        GameSession session = plugin.getGameManager().getSession(player);
       
        if (!isValidGameState(player, session)) { return; }
       
        if (event.isSprinting()) {
            pressedW.put(player.getUniqueId(), true);
            if (DEBUG_MODE) player.sendMessage(ChatColor.YELLOW + "dbg: sprint+w");
            updateDirection(player, Direction.UP);
        }
    }
   
    // FOR TESTING PURPOSES, DON'T REMOVE THIS
    @EventHandler
    public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
        Player player = event.getPlayer();
        GameSession session = plugin.getGameManager().getSession(player);
       
        if (!isValidGameState(player, session)) {
            return;
        }
       
        if (event.isSneaking()) {
            pressedS.put(player.getUniqueId(), true);
            if (DEBUG_MODE) player.sendMessage(ChatColor.YELLOW + "dbg: sneak+s");
            updateDirection(player, Direction.DOWN);
        }
    }
   
    private void resetKeyState(UUID playerId) {
        pressedW.put(playerId, false);
        pressedA.put(playerId, false);
        pressedS.put(playerId, false);
        pressedD.put(playerId, false);
        lastDirection.remove(playerId);
    }
   
    private void registerKeyListeners() {
        protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST,
                PacketType.Play.Client.STEER_VEHICLE) {
            @Override
            public void onPacketReceiving(PacketEvent event) {
                handleSteerVehicle(event);
            }
        });
       
        protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST,
                PacketType.Play.Client.ENTITY_ACTION) {
            @Override
            public void onPacketReceiving(PacketEvent event) {
                handleEntityAction(event);
            }
        });
       
        protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST,
                PacketType.Play.Client.POSITION, PacketType.Play.Client.POSITION_LOOK) {
            @Override
            public void onPacketReceiving(PacketEvent event) {
                handlePosition(event);
            }
        });
       
        protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST,
                PacketType.Play.Client.HELD_ITEM_SLOT) {
            @Override
            public void onPacketReceiving(PacketEvent event) {
                Player player = event.getPlayer();
                Engine engine = (Engine) plugin;
                GameSession session = engine.getGameManager().getSession(player);
               
                if (!isValidGameState(player, session)) {
                    return;
                }
               
                int newSlot = event.getPacket().getIntegers().read(0);
               
                Direction direction = null;
                switch (newSlot) {
                    case 0:
                        direction = Direction.UP;
                        break;
                    case 1:
                        direction = Direction.RIGHT;
                        break;
                    case 2:
                        direction = Direction.DOWN;
                        break;
                    case 3:
                        direction = Direction.LEFT;
                        break;
                    default:
                        break;
                }
               
                if (direction != null) {
                    if (DEBUG_MODE) player.sendMessage(ChatColor.GOLD + "dbg: hb " + newSlot + " - dir: " + direction);
                    updateDirection(player, direction);
                }
            }
        });
       
        Bukkit.getScheduler().runTaskTimer(plugin, this::processKeyStates, 1L, 1L);
    }
   
    private void handleSteerVehicle(PacketEvent event) {
        Player player = event.getPlayer();
        GameSession session = plugin.getGameManager().getSession(player);
       
        if (!isValidGameState(player, session)) { return; }
       
        try {
            PacketContainer packet = event.getPacket();
           
            // paket 0x16 - field (sideways, forward, flags) - bit mask 0x1 jump 0x2 unmount
            if (packet.getFloat().size() < 2) {
                return;
            }
           
            float forward = packet.getFloat().read(0);
            float sideways = packet.getFloat().read(1);
           
            UUID playerId = player.getUniqueId();
           
            if (Math.abs(forward) > 0.01f) {
                boolean isW = forward > 0;
                boolean isS = forward < 0;
                pressedW.put(playerId, isW);
                pressedS.put(playerId, isS);
               
                if (isW) {
                    if (DEBUG_MODE) player.sendMessage(ChatColor.AQUA + "dbg: w pressed");
                    updateDirection(player, Direction.UP);
                } else if (isS) {
                    if (DEBUG_MODE) player.sendMessage(ChatColor.AQUA + "dbg: s pressed");
                    updateDirection(player, Direction.DOWN);
                }
            }
           
            if (Math.abs(sideways) > 0.01f) {
                boolean isD = sideways > 0;
                boolean isA = sideways < 0;
                pressedD.put(playerId, isD);
                pressedA.put(playerId, isA);
               
                if (isD) {
                    if (DEBUG_MODE) player.sendMessage(ChatColor.AQUA + "dbg: sv+d");
                    updateDirection(player, Direction.RIGHT);
                } else if (isA) {
                    if (DEBUG_MODE) player.sendMessage(ChatColor.AQUA + "dbg: sv+a");
                    updateDirection(player, Direction.LEFT);
                }
            }
        } catch (Exception e) {
            plugin.getLogger().warning("err: " + e.getMessage());
        }
    }
   
    private void handleEntityAction(PacketEvent event) {
        Player player = event.getPlayer();
        GameSession session = plugin.getGameManager().getSession(player);
       
        if (!isValidGameState(player, session)) {
            return;
        }
       
        try {
            PacketContainer packet = event.getPacket();
            PlayerAction action = packet.getPlayerActions().read(0);
           
            UUID playerId = player.getUniqueId();
           
            switch (action) {
                case START_SPRINTING:
                    pressedW.put(playerId, true);
                    if (DEBUG_MODE) player.sendMessage(ChatColor.GREEN + "dbg: START_SPRINTING - W");
                    updateDirection(player, Direction.UP);
                    break;
                case STOP_SPRINTING:
                    pressedW.put(playerId, false);
                    break;
                case START_SNEAKING:
                    pressedS.put(playerId, true);
                    if (DEBUG_MODE) player.sendMessage(ChatColor.GREEN + "dbg: START_SNEAKING - S detected");
                    updateDirection(player, Direction.DOWN);
                    break;
                case STOP_SNEAKING:
                    pressedS.put(playerId, false);
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            plugin.getLogger().warning("err action: " + e.getMessage());
        }
    }
   
    private void handlePosition(PacketEvent event) {
        Player player = event.getPlayer();
        GameSession session = plugin.getGameManager().getSession(player);
       
        if (!isValidGameState(player, session)) {
            return;
        }
       
        try {
            double x = event.getPacket().getDoubles().read(0) - player.getLocation().getX();
            double z = event.getPacket().getDoubles().read(2) - player.getLocation().getZ();
           
            if (Math.abs(x) < 0.0001 && Math.abs(z) < 0.0001) {
                return;
            }
           
            UUID playerId = player.getUniqueId();
            Direction direction = null;
            // tuvalete gidip geliyom
            if (Math.abs(x) > Math.abs(z)) {
                if (x > 0) {
                    pressedD.put(playerId, true);
                    direction = Direction.RIGHT;
                    if (DEBUG_MODE) player.sendMessage(ChatColor.BLUE + "pos pckt - d");
                } else {
                    pressedA.put(playerId, true);
                    direction = Direction.LEFT;
                    if (DEBUG_MODE) player.sendMessage(ChatColor.BLUE + "pos pckt - a");
                }
            } else {
                if (z > 0) {
                    pressedS.put(playerId, true);
                    direction = Direction.DOWN;
                    if (DEBUG_MODE) player.sendMessage(ChatColor.BLUE + "pos pckt - s");
                } else {
                    pressedW.put(playerId, true);
                    direction = Direction.UP;
                    if (DEBUG_MODE) player.sendMessage(ChatColor.BLUE + "pos pckt - w");
                }
            }
           
            if (direction != null) {
                updateDirection(player, direction);
            }
        } catch (Exception e) {
        }
    }
   
    @EventHandler(priority = org.bukkit.event.EventPriority.HIGHEST)
    public void onPlayerMove(PlayerMoveEvent event) {
        Player player = event.getPlayer();
        GameSession session = plugin.getGameManager().getSession(player);
       
        if (!isValidGameState(player, session)) {
            return;
        }
       
        double dx = event.getTo().getX() - event.getFrom().getX();
        double dz = event.getTo().getZ() - event.getFrom().getZ();
       
        if (Math.abs(dx) < 0.0001 && Math.abs(dz) < 0.0001) { return; }
       
        UUID playerId = player.getUniqueId();
        Direction direction = null;
       
        if (Math.abs(dx) > Math.abs(dz)) {
            if (dx > 0) {
                pressedD.put(playerId, true);
                direction = Direction.RIGHT;
                if (DEBUG_MODE) player.sendMessage(ChatColor.DARK_GREEN + "mov ev - d");
            } else {
                pressedA.put(playerId, true);
                direction = Direction.LEFT;
                if (DEBUG_MODE) player.sendMessage(ChatColor.DARK_GREEN + "mov ev - a");
            }
        } else {
            if (dz > 0) {
                pressedS.put(playerId, true);
                direction = Direction.DOWN;
                if (DEBUG_MODE) player.sendMessage(ChatColor.DARK_GREEN + "mov ev - s");
            } else {
                pressedW.put(playerId, true);
                direction = Direction.UP;
                if (DEBUG_MODE) player.sendMessage(ChatColor.DARK_GREEN + "mov ev - w");
            }
        }
       
        if (direction != null) {
            updateDirection(player, direction);
        }
    }
   
    private void processKeyStates() {
        for (Player player : Bukkit.getOnlinePlayers()) {
            GameSession session = plugin.getGameManager().getSession(player);
           
            if (!isValidGameState(player, session)) { continue; }
           
            UUID playerId = player.getUniqueId();
           
            boolean w = pressedW.getOrDefault(playerId, false);
            boolean a = pressedA.getOrDefault(playerId, false);
            boolean s = pressedS.getOrDefault(playerId, false);
            boolean d = pressedD.getOrDefault(playerId, false);
           
            Direction direction = null;
            if (w) direction = Direction.UP;
            else if (s) direction = Direction.DOWN;
            else if (a) direction = Direction.LEFT;
            else if (d) direction = Direction.RIGHT;
           
            if (direction != null && direction != lastDirection.getOrDefault(playerId, null)) {
                updateDirection(player, direction);
                resetKeyState(playerId);
            }
        }
    }
   
    private void updateDirection(Player player, Direction direction) {
        GameSession session = plugin.getGameManager().getSession(player);
        if (!isValidGameState(player, session)) {
            return;
        }
       
        UUID playerId = player.getUniqueId();
        long now = System.currentTimeMillis();
        long lastChange = lastDirectionChange.getOrDefault(playerId, 0L);
       
        if (now - lastChange > COOLDOWN_MS) {
            // cache lazim
            Direction current = lastDirection.getOrDefault(playerId, null);
            if (direction != current) {
                plugin.getGameManager().setDirection(player, direction);
                if (DEBUG_MODE) {
                    player.sendMessage(ChatColor.GOLD + "dir set " + direction);
                }
               
                lastDirectionChange.put(playerId, now);
                lastDirection.put(playerId, direction);
            }
        }
    }
   
    private boolean isValidGameState(Player player, GameSession session) {
        return session != null &&
               player.getWorld() == plugin.getGameWorld() &&
               session.getPlayerState() == PlayerState.PLAYING;
    }
   
    private void startDebugTask() {
        Bukkit.getScheduler().runTaskTimer(plugin, () -> {
            for (Player player : Bukkit.getOnlinePlayers()) {
                GameSession session = plugin.getGameManager().getSession(player);
                if (session != null && session.getPlayerState() == PlayerState.PLAYING) {
                    UUID playerId = player.getUniqueId();
                    Direction current = lastDirection.getOrDefault(playerId, null);
                    if (current != null) {
                        player.spigot().sendMessage(net.md_5.bungee.api.ChatMessageType.ACTION_BAR,
                            net.md_5.bungee.api.chat.TextComponent.fromLegacyText(ChatColor.YELLOW + "current directaion: " + current));
                    }
                }
            }
        }, 20L, 20L);
    }
   
    public void cleanup() {
        protocolManager.removePacketListeners(plugin);
        lastDirectionChange.clear();
        lastDirection.clear();
        pressedW.clear();
        pressedA.clear();
        pressedS.clear();
        pressedD.clear();
    }
   
    public void setupPlayerForKeyDetection(Player player) {
        if (player == null) return;
       
        player.setGameMode(GameMode.SPECTATOR);
        player.setAllowFlight(true);
        player.setFlying(true);
        player.setFlySpeed(0.1f);
        player.setWalkSpeed(0.1f);
       
        resetKeyState(player.getUniqueId());
    }
}

Ayrıca teşekkür ederim, proje 5 saatte bittiyse 1 saati bu olaydı zaten neredeyse kod biraz shit o yüzden kusura bakma :D

Bir de, config'den değiştirilebiliyor UI tercihi. Videoyu çekerken LEGACY'de kalmış.
1743519395843.webp
 
Son düzenleme:
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...

Hala Discord sunucumuza katılmadın mı?

Büyük bir topluluğun parçası ol, etkinliklere katıl ve özel hediyeler kazanma şansı yakala!

Şimdi Katıl
Üst