Làm thế nào để thực hiện các hiệu ứng vũ khí và áo giáp đặc biệt (ví dụ: ma cà rồng, thánh, khiên sát thương, gai)?


7

Tôi đang làm việc trên hệ thống kiểm kê cho trò chơi của mình và quan tâm đến cách tôi triển khai các thuộc tính vũ khí và áo giáp bổ sung không chỉ là sát thương hoặc áo giáp?

Nếu tất cả những gì tôi có là sát thương và áo giáp, phương trình rất đơn giản: sát thương = sát thương vũ khí - áo giáp;

Nhưng tôi đang tìm kiếm trải nghiệm người dùng thú vị hơn - cụ thể là các vật phẩm có 2-3 thuộc tính sửa đổi các cơ chế trò chơi khác nhau.

Ví dụ: tôi có thể sử dụng một loạt các cờ và viết một câu lệnh if / other lớn trong phương thức tấn công của mình và kiểm tra tất cả những điều này tại các điểm thích hợp:

if (vũ khí là ma cà rồng) {chữa lành kẻ tấn công cho x}

if (vũ khí là thánh) {kiểm tra loại hậu vệ, thêm sát thương}

if (áo giáp hấp thụ x sát thương đầu tiên) {giảm sát thương cho hậu vệ bằng x}

Một cách khác mà tôi nghĩ có thể tốt hơn là mẫu thiết kế trang trí - dần dần bao bọc đầu ra của một sáng tạo vũ khí này sang một vũ khí khác:

public class Main {

    public static final void main(String[] args) {
    Weapon w = new MeleeWeapon();

        w = new Holy(w);
        w = new Vampiric;
        w = new Enchanted(w,1);

        Damage damage = w.damage();

    }

}

Dường như với tôi, người trang trí sẽ cho phép tôi viết mã linh hoạt hơn và thêm nhiều loại sau, nhưng tôi không chắc liệu nó có chuyển các câu lệnh if / other vào phương thức đặc tính vũ khí hay không.


Câu trả lời:


7

Bản thân các từ giúp bạn: vũ khí chỉ là vật mang cho hiệu ứng. Một số là tức thời (thiệt hại), số khác là lâu hơn (chất độc).

Phạm vi của các hiệu ứng cũng khá lớn: một số hiệu ứng ảnh hưởng đến chủ sở hữu vũ khí, một số khác là đối thủ. Và hầu hết thời gian, bạn cần đưa tất cả chúng vào tài khoản (tuy nhiên, bạn có thể dễ dàng nhanh chóng tìm kiếm để biết cái nào được áp dụng).

def Attack( attacker, receiver) :
    status = receiver.status() # original LP, MP, etc
    impacts = [] # the list of impacts (poison, speed, etc) to be applied
                 # impact need to be sortable by category, so we can 
                 # enhance them or cancel them
    for effect in attacker.effects:
        # accumulation the instantaneous impacts
         if effect.instantaneous:
             impacts.append( effects.apply(status, impacts) )
        # some effects last a while, an active instance will be carried by the receiver
        # those instance have a tick method and will stop after a moment and be removed
         elif effect.lasting:
             receiver.effects.append( effect.get_copy() )
         else:
             continue
    # we need to apply receiver effects as some may cancel some impacts of the attacker
    for effect in receiver.effects:        
         if effect.on_impacts: # effects that can modify impacts
             impacts.append( effects.apply(status, impacts) )
         elif effect.on_effects: # effects than can modify lasting effects
             receiver.effects = effect.filter(receiver.effects, status )
         else:
             continue


    # lastly, we apply all the impacts.
    status.change( impacts )
    receiver.status = status

Ví dụ, tính toán của một chiến binh mang theo thanh kiếm có chất độc bảo vệ được đâm bởi một con bọ cạp khổng lồ sẽ giống như:

Warrior.effects = [ PoisonProtection(.30), #effect.on_impact,
                    CannotBeStun(), #effect.on_effects,
                    FireDamage(+15%), #effect.instantaneous
                    SensibleToIce(+15%), #effect.instantaneous ]

Scorpion.effects = [ SimpleDamage(min=10, max=30),
                     PoisonDamage( 30),
                     LastingPoisonDamage( dmg_per_sec=3, length=15) ]

Điều này cần được mở rộng để quản lý hiệu ứng khu vực nhưng bạn có được ý tưởng chung.


Tôi thực sự thích câu trả lời của bạn, đặc biệt là cách các hiệu ứng có thể là tức thời hoặc ảnh hưởng đến các hiệu ứng khác. Tôi đã suy nghĩ về cách thực hiện những thứ như "không thể bị choáng", và ở đây bạn có nó!
Alex Stone

2

newing lặp đi lặp lại và các bước nhảy này sẽ phát sinh giữa các vị trí bộ nhớ nơi đặt đối tượng ban đầu và các hàm bao khác nhau của nó, sẽ tốn kém hơn so với các điều kiện mở rộng mà bạn đề cập hoặc cách tiếp cận được cung cấp dưới đây. Ngoài ra, tôi sẽ do dự trong việc sử dụng Mẫu trang trí trong trường hợp này bởi vì không có thứ tự rõ ràng nào trong đó các nhà trang trí sẽ áp dụng, do đó làm cho mã có khả năng gây nhầm lẫn để gỡ lỗi; tốt hơn là có tất cả các tùy chọn được liệt kê tuyến tính, nhưng được gói gọn riêng lẻ.

Những gì tôi muốn đề xuất sẽ là các con trỏ hàm, hàm xử lý hoặc Mẫu chiến lược cho các ngôn ngữ không hỗ trợ các hàm hạng nhất hoặc ở nơi có mong muốn mạnh mẽ để làm việc với các giao diện cố định.

Trong lớp vũ khí của bạn, giữ một loạt các tham chiếu đến các con trỏ chức năng, hàm functor hoặc chiến lược có thể đại diện cho các hiệu ứng có thể khác nhau và gọi từng loại (không phải null) tại thời điểm bạn cần xử lý vũ khí. Bạn có thể giữ các tham chiếu này với tư cách là thành viên hoặc dưới dạng các mục trong một mảng hoặc từ điển (năng động hơn và khả thi hơn với công cụ tạo tập lệnh, nhưng cũng chậm hơn một chút). Cố gắng duy trì giai đoạn cập nhật trong đó bạn đang giải quyết tất cả các hiệu ứng vũ khí, không chỉ thiệt hại .

PS Điều này liên quan khá chặt chẽ đến cách chúng ta thường xây dựng các hệ thống thành phần thực thể dựa trên OO, mặc dù sự khác biệt phải được thực hiện ở đây là chúng ta không coi mỗi trong số chúng là một thành phần của một thực thể, mà là một thành phần của vũ khí thường được tham chiếu bởi vũ khí hoặc thành phần tay của một thực thể. Điều đó nói rằng, một vũ khí có thể tự nó là một loại thực thể.

PPS Hãy cẩn thận áp dụng các mẫu thiết kế phát triển phần mềm (đọc: kinh doanh) truyền thống khi viết các trò chơi (thời gian thực). Không phải tất cả trong số chúng gần như có thể áp dụng ở đây như trong thế giới rộng lớn hơn, vì kiến ​​trúc trò chơi đòi hỏi một loạt các mối quan tâm rất khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.