找回密码
 中文实名注册
搜索
查看: 2367|回复: 75

陈子桐的作品

[复制链接]

6

主题

60

回帖

858

积分

高级会员

积分
858
发表于 2026-2-11 08:43:07 | 显示全部楼层 |阅读模式
陈子桐的作品

点评

4.3打字42积分20  发表于 2026-4-3 11:14
回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 3 天前 | 显示全部楼层
0000.火柴人

main.py

23.76 KB, 下载次数: 38

点评

8.9打字70积分35  发表于 3 天前
回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 5 天前 | 显示全部楼层
666.森林冰火人

main.py

10.09 KB, 下载次数: 137

点评

8.7打字62积分30  发表于 5 天前
回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 7 天前 | 显示全部楼层
9999999食谱

main.py

4.88 KB, 下载次数: 0

售价: 10 金钱  [记录]  [购买]

回复

使用道具 举报

38

主题

160

回帖

1万

积分

论坛元老

积分
16590
发表于 2026-8-2 11:43:07 | 显示全部楼层
import pygame
import socket
import pickle
import sys

# ===================== 这里一定要改!!=====================
SERVER_IP = "192.168.2.33"
# 本地同一台电脑测试填 "127.0.0.1"
PORT = 5555
# =========================================================

WIDTH, HEIGHT = 900, 600
FPS = 60
PLAYER_SIZE = 50
ATTACK_RANGE = 70

WHITE = (255, 255, 255)
RED = (220, 30, 30)
BLUE = (30, 80, 220)
GREEN = (40, 180, 40)
BLACK = (0, 0, 0)

# ========= 固定收发函数(解决粘包核心!不要删除)=========
def send_data(sock, obj):
    data = pickle.dumps(obj)
    sock.sendall(len(data).to_bytes(4, byteorder='big'))
    sock.sendall(data)

def recv_data(sock):
    length_raw = sock.recv(4)
    if not length_raw:
        return None
    data_len = int.from_bytes(length_raw, byteorder='big')
    buffer = b''
    while len(buffer) < data_len:
        packet = sock.recv(data_len - len(buffer))
        if not packet:
            return None
        buffer += packet
    return pickle.loads(buffer)
# ======================================================

class Network:
    def __init__(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.addr = (SERVER_IP, PORT)
        self.player_id = None

    def connect(self):
        try:
            self.client.connect(self.addr)
            self.player_id = recv_data(self.client)
            print(f"✅ 连接成功!你是玩家{self.player_id}")
            return self.player_id
        except Exception as e:
            print("❌ 无法连接服务器!检查IP、防火墙、是否同局域网", e)
            return None

    def send(self, obj):
        try:
            send_data(self.client, obj)
            return recv_data(self.client)
        except Exception as e:
            print("通信异常:", e)
            return None

    def close(self):
        self.client.close()

def main():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("联网双人近战对战【客户端】")
    clock = pygame.time.Clock()
    font = pygame.font.SysFont(None, 48)

    net = Network()
    pid = net.connect()
    if pid is None:
        pygame.quit()
        return

    game_over = False
    winner = -1

    while True:
        current_time = pygame.time.get_ticks()
        keys = {"left":False, "right":False, "up":False, "down":False}
        attack = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                net.close()
                pygame.quit()
                sys.exit()

        pressed = pygame.key.get_pressed()
        if pid == 0:
            # 玩家0 蓝色:WASD + 空格攻击
            keys["left"] = pressed[pygame.K_a]
            keys["right"] = pressed[pygame.K_d]
            keys["up"] = pressed[pygame.K_w]
            keys["down"] = pressed[pygame.K_s]
            attack = pressed[pygame.K_SPACE]
        else:
            # 玩家1 红色:方向键 + 小键盘0攻击
            keys["left"] = pressed[pygame.K_LEFT]
            keys["right"] = pressed[pygame.K_RIGHT]
            keys["up"] = pressed[pygame.K_UP]
            keys["down"] = pressed[pygame.K_DOWN]
            attack = pressed[pygame.K_KP0]

        receive_data = net.send((keys, attack, current_time))
        if receive_data is None:
            print("服务器断开连接")
            break
        p1, p2 = receive_data

        # 胜负判定
        if p1.hp <= 0 and not game_over:
            game_over = True
            winner = 1
        elif p2.hp <= 0 and not game_over:
            game_over = True
            winner = 0

        # 渲染
        screen.fill((26,26,26))
        pygame.draw.rect(screen, p1.color, pygame.Rect(p1.x, p1.y, PLAYER_SIZE, PLAYER_SIZE))
        pygame.draw.rect(screen, p2.color, pygame.Rect(p2.x, p2.y, PLAYER_SIZE, PLAYER_SIZE))

        # 攻击范围特效
        if p1.is_attacking:
            ar = pygame.Rect(p1.x - ATTACK_RANGE//2, p1.y, ATTACK_RANGE+PLAYER_SIZE, PLAYER_SIZE)
            pygame.draw.rect(screen, (100,100,255), ar, 2)
        if p2.is_attacking:
            ar = pygame.Rect(p2.x - ATTACK_RANGE//2, p2.y, ATTACK_RANGE+PLAYER_SIZE, PLAYER_SIZE)
            pygame.draw.rect(screen, (255,100,100), ar, 2)

        # 血条
        pygame.draw.rect(screen, BLACK, (p1.x, p1.y-12, PLAYER_SIZE, 8))
        pygame.draw.rect(screen, GREEN, (p1.x, p1.y-12, PLAYER_SIZE*(p1.hp/100), 8))
        pygame.draw.rect(screen, BLACK, (p2.x, p2.y-12, PLAYER_SIZE, 8))
        pygame.draw.rect(screen, GREEN, (p2.x, p2.y-12, PLAYER_SIZE*(p2.hp/100), 8))

        if game_over:
            if winner == 0:
                text = font.render("蓝色玩家胜利!", True, BLUE)
            else:
                text = font.render("红色玩家胜利!", True, RED)
            screen.blit(text, (WIDTH//2 - 130, HEIGHT//2))

        pygame.display.flip()
        clock.tick(FPS)

if __name__ == "__main__":
    main()
回复

使用道具 举报

38

主题

160

回帖

1万

积分

论坛元老

积分
16590
发表于 2026-8-2 11:36:21 | 显示全部楼层
import socket
import threading
import pickle

# ==================== 配置(和客户端保持一致!)====================
PORT = 5555
SPEED = 5
ATTACK_RANGE = 70
ATTACK_COOLDOWN = 400
DAMAGE = 25
KNOCKBACK = 8

RED = (220, 30, 30)
BLUE = (30, 80, 220)
# ==================================================================

class Player:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.hp = 100
        self.last_attack = 0
        self.is_attacking = False

# 初始化两名玩家
p1 = Player(100, 250, BLUE)   # 玩家0 蓝色
p2 = Player(700, 250, RED)    # 玩家1 红色

clients = []
lock = threading.Lock()

def handle_client(conn, addr, pid):
    global p1, p2
    print(f"✅ 玩家{pid} 已连接:{addr}")
    # 先把玩家ID发给客户端
    conn.send(pickle.dumps(pid))

    while True:
        try:
            data = pickle.loads(conn.recv(4096))
            keys, attack, now_time = data

            with lock:
                # 更新当前玩家移动
                current_player = p1 if pid == 0 else p2
                if keys["left"]:
                    current_player.x -= SPEED
                if keys["right"]:
                    current_player.x += SPEED
                if keys["up"]:
                    current_player.y -= SPEED
                if keys["down"]:
                    current_player.y += SPEED

                # 攻击判定
                current_player.is_attacking = False
                if attack and now_time - current_player.last_attack > ATTACK_COOLDOWN:
                    current_player.last_attack = now_time
                    current_player.is_attacking = True

                    # 攻击命中检测
                    target = p2 if pid == 0 else p1
                    hit_box = (current_player.x - ATTACK_RANGE//2, current_player.y, ATTACK_RANGE+50, 50)
                    target_box = (target.x, target.y, 50, 50)

                    # 碰撞检测
                    hx1, hy1, hw, hh = hit_box
                    tx1, ty1, tw, th = target_box
                    if hx1 < tx1+tw and hx1+hw > tx1 and hy1 < ty1+th and hy1+hh > ty1:
                        target.hp -= DAMAGE
                        # 击退效果
                        if pid == 0:
                            target.x += KNOCKBACK
                        else:
                            target.x -= KNOCKBACK

            # 把两名玩家最新状态发回客户端
            send_data = (p1, p2)
            conn.send(pickle.dumps(send_data))

        except Exception as e:
            print(f"❌ 玩家{pid} 连接断开:", e)
            break
    conn.close()

def start_server():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(("0.0.0.0", PORT))
    server.listen()
    print(f"🚀 服务器启动成功!端口 {PORT},等待两名玩家连接...")
    player_index = 0

    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr, player_index))
        thread.start()
        player_index += 1

if __name__ == "__main__":
    start_server()
回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 2026-8-2 11:21:30 | 显示全部楼层
import socket
import threading
import pickle

# ===================== 配置 =====================
WIDTH, HEIGHT = 900, 600
PLAYER_SIZE = 50
SPEED = 5
ATTACK_RANGE = 70
ATTACK_COOLDOWN = 400
DAMAGE = 25
KNOCKBACK = 8
PORT = 5555

RED = (220, 30, 30)
BLUE = (30, 80, 220)

# ===================== 玩家类 =====================
class Player:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.hp = 100
        self.last_attack = 0
        self.is_attacking = False

    def get_rect(self):
        import pygame
        return pygame.Rect(self.x, self.y, PLAYER_SIZE, PLAYER_SIZE)

    def move(self, dx, dy):
        self.x += dx * SPEED
        self.y += dy * SPEED
        self.x = max(0, min(WIDTH - PLAYER_SIZE, self.x))
        self.y = max(0, min(HEIGHT - PLAYER_SIZE, self.y))

    def attack(self, current_time):
        if current_time - self.last_attack > ATTACK_COOLDOWN:
            self.last_attack = current_time
            self.is_attacking = True
            return True
        return False

    def reset_attack(self):
        self.is_attacking = False

    def take_damage(self):
        self.hp -= DAMAGE
        if self.hp < 0:
            self.hp = 0

def update_player(player, input_data):
    keys, attack, time = input_data
    dx, dy = 0, 0
    if keys["left"]: dx -= 1
    if keys["right"]: dx += 1
    if keys["up"]: dy -= 1
    if keys["down"]: dy += 1
    player.move(dx, dy)
    if attack:
        player.attack(time)
    else:
        player.reset_attack()

def check_attack_hit(p1layer, p2layer):
    import pygame
    if p1.is_attacking:
        attack_rect = pygame.Rect(p1.x - ATTACK_RANGE//2, p1.y, ATTACK_RANGE+PLAYER_SIZE, PLAYER_SIZE)
        if attack_rect.colliderect(p2.get_rect()):
            p2.take_damage()
            if p1.x < p2.x:
                p2.x += KNOCKBACK
            else:
                p2.x -= KNOCKBACK
            p1.is_attacking = False
    if p2.is_attacking:
        attack_rect = pygame.Rect(p2.x - ATTACK_RANGE//2, p2.y, ATTACK_RANGE+PLAYER_SIZE, PLAYER_SIZE)
        if attack_rect.colliderect(p1.get_rect()):
            p1.take_damage()
            if p2.x < p1.x:
                p1.x += KNOCKBACK
            else:
                p1.x -= KNOCKBACK

# ===================== 服务器主程序 =====================
def start_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("0.0.0.0", PORT))
    server_socket.listen(2)
    print(f"✅ 服务器启动成功!端口 {PORT}")
    print("等待两名玩家连接...")

    conn1, addr1 = server_socket.accept()
    print(f"🎮 玩家1(蓝色) 已连接:{addr1}")
    conn1.send(pickle.dumps(0))

    conn2, addr2 = server_socket.accept()
    print(f"🎮 玩家2(红色) 已连接:{addr2}")
    conn2.send(pickle.dumps(1))

    p1 = Player(100, HEIGHT//2, BLUE)
    p2 = Player(WIDTH - 150, HEIGHT//2, RED)

    while True:
        try:
            data1 = pickle.loads(conn1.recv(4096))
            data2 = pickle.loads(conn2.recv(4096))

            update_player(p1, data1)
            update_player(p2, data2)
            check_attack_hit(p1, p2)

            send_package = (p1, p2)
            conn1.send(pickle.dumps(send_package))
            conn2.send(pickle.dumps(send_package))
        except Exception as e:
            print("❌ 连接断开!", e)
            break
    conn1.close()
    conn2.close()

if __name__ == "__main__":
    start_server()
回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 2026-8-2 11:12:33 | 显示全部楼层
import pygame
import socket
import pickle
import sys

# ===================== 这里一定要改!!=====================
SERVER_IP = "192.168.1.105"   # 修改为运行server.py电脑的内网IP
# 本地同一台电脑测试填 "127.0.0.1"
PORT = 5555
# =========================================================

WIDTH, HEIGHT = 900, 600
FPS = 60
PLAYER_SIZE = 50
ATTACK_RANGE = 70

WHITE = (255, 255, 255)
RED = (220, 30, 30)
BLUE = (30, 80, 220)
GREEN = (40, 180, 40)
BLACK = (0, 0, 0)

class Network:
    def __init__(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.addr = (SERVER_IP, PORT)
        self.player_id = None

    def connect(self):
        try:
            self.client.connect(self.addr)
            self.player_id = pickle.loads(self.client.recv(4096))
            print(f"✅ 连接成功!你是玩家{self.player_id}")
            return self.player_id
        except Exception as e:
            print("❌ 无法连接服务器!检查IP、防火墙、是否同局域网", e)
            return None

    def send(self, obj):
        try:
            self.client.send(pickle.dumps(obj))
            return pickle.loads(self.client.recv(4096))
        except:
            return None

    def close(self):
        self.client.close()

def main():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("联网双人近战对战【客户端】")
    clock = pygame.time.Clock()
    font = pygame.font.SysFont(None, 48)

    net = Network()
    pid = net.connect()
    if pid is None:
        pygame.quit()
        return

    game_over = False
    winner = -1

    while True:
        current_time = pygame.time.get_ticks()
        keys = {"left":False, "right":False, "up":False, "down":False}
        attack = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                net.close()
                pygame.quit()
                sys.exit()

        pressed = pygame.key.get_pressed()
        if pid == 0:
            # 玩家0 蓝色:WASD + 空格攻击
            keys["left"] = pressed[pygame.K_a]
            keys["right"] = pressed[pygame.K_d]
            keys["up"] = pressed[pygame.K_w]
            keys["down"] = pressed[pygame.K_s]
            attack = pressed[pygame.K_SPACE]
        else:
            # 玩家1 红色:方向键 + 小键盘0攻击
            keys["left"] = pressed[pygame.K_LEFT]
            keys["right"] = pressed[pygame.K_RIGHT]
            keys["up"] = pressed[pygame.K_UP]
            keys["down"] = pressed[pygame.K_DOWN]
            attack = pressed[pygame.K_KP0]

        receive_data = net.send((keys, attack, current_time))
        if receive_data is None:
            print("服务器断开连接")
            break
        p1, p2 = receive_data

        # 胜负判定
        if p1.hp <= 0 and not game_over:
            game_over = True
            winner = 1
        elif p2.hp <= 0 and not game_over:
            game_over = True
            winner = 0

        # 渲染
        screen.fill((26,26,26))
        pygame.draw.rect(screen, p1.color, pygame.Rect(p1.x, p1.y, PLAYER_SIZE, PLAYER_SIZE))
        pygame.draw.rect(screen, p2.color, pygame.Rect(p2.x, p2.y, PLAYER_SIZE, PLAYER_SIZE))

        # 攻击范围特效
        if p1.is_attacking:
            ar = pygame.Rect(p1.x - ATTACK_RANGE//2, p1.y, ATTACK_RANGE+PLAYER_SIZE, PLAYER_SIZE)
            pygame.draw.rect(screen, (100,100,255), ar, 2)
        if p2.is_attacking:
            ar = pygame.Rect(p2.x - ATTACK_RANGE//2, p2.y, ATTACK_RANGE+PLAYER_SIZE, PLAYER_SIZE)
            pygame.draw.rect(screen, (255,100,100), ar, 2)

        # 血条
        pygame.draw.rect(screen, BLACK, (p1.x, p1.y-12, PLAYER_SIZE, 8))
        pygame.draw.rect(screen, GREEN, (p1.x, p1.y-12, PLAYER_SIZE*(p1.hp/100), 8))
        pygame.draw.rect(screen, BLACK, (p2.x, p2.y-12, PLAYER_SIZE, 8))
        pygame.draw.rect(screen, GREEN, (p2.x, p2.y-12, PLAYER_SIZE*(p2.hp/100), 8))

        if game_over:
            if winner == 0:
                text = font.render("蓝色玩家胜利!", True, BLUE)
            else:
                text = font.render("红色玩家胜利!", True, RED)
            screen.blit(text, (WIDTH//2 - 130, HEIGHT//2))

        pygame.display.flip()
        clock.tick(FPS)

if __name__ == "__main__":
    main()
回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 2026-8-2 10:54:34 | 显示全部楼层
33434.聊天

main.py

399 Bytes, 下载次数: 0

售价: 9 金钱  [记录]  [购买]

回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 2026-7-31 11:47:58 | 显示全部楼层
吃豆人

main.py

5.42 KB, 下载次数: 347

回复

使用道具 举报

6

主题

60

回帖

858

积分

高级会员

积分
858
 楼主| 发表于 2026-7-31 11:38:01 | 显示全部楼层
888枪战

main.py

9.11 KB, 下载次数: 0

售价: 10 金钱  [记录]  [购买]

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表