2011-09-08 36 views
23

Trò chơi cần quyền truy cập ở mức độ thấp vào đầu vào bàn phím. Trên Windows, có DirectInput. Nhưng các nhà phát triển trò chơi Mac OS X sử dụng công nghệ nào?Trò chơi Mac OS X có thể nhận các sự kiện nhập bàn phím cấp thấp như thế nào?

Rõ ràng, có đủ trò chơi Mac mà có được bàn phím đầu vào vừa phải, nếu không có sự hạn chế của các giải pháp thường được gọi:

Giải pháp # 1: Use keyUp/keyDown events

-(void)keyUp:(NSEvent*)event; 
-(void)keyDown:(NSEvent*)event; 

nhược điểm Inacceptable: keyDown các sự kiện được lặp lại dựa trên cài đặt tùy chọn hệ thống cho "tốc độ lặp lại chính" và "độ trễ lặp lại chính". Điều này gây ra một sự kiện keyDown ban đầu theo sau bởi một tạm dừng trước khi nó bắt đầu lặp lại với tốc độ được xác định bởi một thiết lập tùy chọn hệ thống. Không thể sử dụng giải pháp này cho các sự kiện quan trọng liên tục.

Tôi tự hỏi liệu hành vi lặp lại chính có thể bị vô hiệu hóa không? Tôi cho rằng bạn có thể đọc khóa keyDown đầu tiên, sau đó nhớ trạng thái "key with keyCode x is down" trong lớp của bạn cho đến khi nhận được sự kiện keyUp cho khóa đó, do đó bỏ qua sự chậm trễ lặp lại và các vấn đề về tốc độ lặp lại.

Giải pháp # 2: Use Quarts Event Taps

Xem Quartz Event Services Reference. Nó dường như đủ thấp.

Hạn chế không thể chấp nhận: yêu cầu bật thiết bị hỗ trợ trong tùy chọn hệ thống trong Universal Access - Bàn phím. Mặc dù điều này có thể được bật theo mặc định, không có gì đảm bảo rằng nó có thể bị tắt trên một số hệ thống.

Tôi cũng đọc rằng các sự kiện Quartz yêu cầu ứng dụng chạy dưới dạng gốc, nhưng không tìm thấy xác nhận nào cho điều này.

Giải pháp # 3: Carbon Events/IOKit HID

Các Carbon Event Manager Reference được đánh dấu là di sản và không nên được sử dụng cho sự phát triển mới.

Hạn chế không thể chấp nhận: không ai biết sự kiện Carbon sẽ tiếp tục được hỗ trợ trong các phiên bản Mac OS trong tương lai.

Ngoài Carbon là một khung kế thừa, điều này vẫn có vẻ là giải pháp tốt nhất. Nhưng có bất kỳ hạn chế nào khác đối với việc sử dụng Sự kiện Carbon không?

Câu hỏi:

Những công nghệ làm Mac OS X phát triển game sử dụng để tiếp nhận các sự kiện bàn phím đầu vào ở mức độ thấp? Nếu họ sử dụng một trong những công nghệ trên, làm thế nào để họ làm việc xung quanh những hạn chế tôi đã đề cập?

UPDATE:

tôi cuối cùng đã quay sang sử dụng các thông điệp NSEvent thường xuyên và bọc chúng trong một neat API for polling the keyboard states.

+2

Tại sao hành vi lặp lại cho khóaDown: không được chấp nhận? Bạn không thể bỏ qua các sự kiện bổ sung cho đến khi bạn nhận được một keyUp ;? – Flyingdiver

+6

Tôi không thực sự biết giải pháp tốt nhất là gì nhưng liên quan đến nhược điểm của giải pháp # 1 - 'NSEvent' có phương thức' isARepeat' để xác định xem sự kiện có phải là kết quả của sự lặp lại khóa tự động hay không. Bạn có thể đơn giản bỏ qua chúng và giả sử khóa được nhấn liên tục cho đến khi bạn nhận được một sự kiện 'keyUp:' tương ứng. – omz

+0

Tôi đã thêm điều này làm ghi chú cho giải pháp # 1. Những gì tôi đã hy vọng cho là một khuôn khổ cho các nhà phát triển trò chơi mà chỉ đơn giản là sẽ cho phép bạn gọi một phương pháp như isKeyDown: (UInt16) virtualKeyCode. – LearnCocos2D

Trả lời

9

Tôi đã có may mắn với # 3, nhưng nó đòi hỏi rất nhiều nâng nặng nếu bạn muốn hỗ trợ bất cứ điều gì ngoài bàn phím.

Một điểm nhanh trước khi chúng tôi đi sâu vào, Carbon và IOKit HID là hai điều riêng biệt. Carbon có thể biến mất vào một thời điểm nào đó. Nhưng IOKit HID là ở đây để ở lại và chỉ có một facelift đẹp trong 10.5.

Để biết ví dụ đầy đủ về cách công cụ này phù hợp với nhau, hãy xem https://github.com/OpenEmu/OpenEmu/blob/master/OpenEmu/OEHIDManager.m. Đó là một phần nhỏ của câu đố như có các tập tin khác trong đó là tốt.

Các tài liệu cho những gì bạn đang muốn làm có thể được tìm thấy http://developer.apple.com/library/mac/#documentation/DeviceDrivers/Conceptual/HID/new_api_10_5/tn2187.html

Một lần nữa, điều này sẽ không biến mất bất cứ lúc nào sớm và hoàn toàn tách biệt với Carbon và Carbon Sự kiện.

0

Ngoài ra còn có một số lớp Device trong polkit (obj-C toolkit) bao gồm ...

  • HIDController sử dụng các thiết bị USB HID
  • AppleRemote sử dụng Apple Remote
  • MidiController sử dụng Midi thiết bị
  • OSCBộ điều khiển để sử dụng thiết bị tương thích OSC qua UDP
  • SerialPort để sử dụng bất kỳ thiết bị cổng nối tiếp nào
  • SC2004LCDModule để sử dụng SC 2004 từ siliconcraft.net

http://code.google.com/p/polkit/

0

Tôi tìm thấy một ví dụ rất tốt về using Quartz Event Taps.

tuy nhiên vấn đề là:

  1. với nhiều loại sự kiện nào đó, người sử dụng cần để chạy các ứng dụng trong đặc quyền root. ví dụ: chặn các sự kiện keydown và keyup yêu cầu root.

  2. chặn là hệ thống rộng, có nghĩa là khi chương trình chạy, nó sẽ nắm bắt tất cả các sự kiện chính ngay cả những sự kiện được gửi đến các ứng dụng khác. thực hiện cần phải rất cẩn thận để không phá vỡ các ứng dụng khác.

2

Tôi đến muộn bên này, nhưng đây là giải pháp cho trò chơi OSX tôi đang viết bằng Swift. Nó rất đơn giản và dường như hoạt động khá tốt.

Trước tiên, bạn có thể đặt mã này trong bộ điều khiển mà đang nhận được sự kiện bàn phím:

var keysDown = Set<UInt16>() 

override func keyDown(e: NSEvent) { 
    keysDown.insert(e.keyCode) 
} 

override func keyUp(e: NSEvent) { 
    keysDown.remove(e.keyCode) 
} 

Sau đó, các bộ phận khác của hệ thống có thể xác định xem một phím đặc biệt là xuống:

if (keysDown.contains(49)) { 
    // space bar is down 
} 

Hoặc lặp qua tất cả các phím hiện đang được nhấn

for char in keysDown { 

    switch char { 

    case 49: 
     // space 
     player.jump() 
    case 126: 
     // up 
     player.moveForward() 
    case 124: 
     // right 
     player.turnRight() 

     // ... etc ... 

    default: 
     // during development I have this line so I can easily see which keys have which codes 
     print(char) 
    } 
} 

Các khóa lưu ýDown là S wift Set, do đó bạn không phải lo lắng về các bản sao hoặc thứ tự. Một chìa khóa hoặc là trong tập hợp hoặc nó không phải là.

Tôi không quá chắc chắn về cách mã hóa tiêu chuẩn. Nhưng bạn có thể cung cấp một trang cấu hình bàn phím nơi người dùng có thể nhập các phím cho mỗi hành động, và sau đó lưu bất kỳ mã khóa nào xảy ra.

+0

thực sự khá thanh lịch như thế này, nhưng nó không thu thập các phím bổ trợ. – 2075

1

Ok vì vậy tôi thực sự đến muộn với bữa tiệc nhưng tôi nghĩ rằng tôi chỉ là thẳng đến điểm và tương tự như giải pháp ông Howards ở trên. Hãy ghi nhớ đầu vào này đang được sử dụng để điều khiển máy ảnh trong trò chơi SpriteKit. Bằng cách này bạn sẽ có được chuyển động liên tục trơn tru và dừng chân chính xác.

let moveRight: SKAction = SKAction.repeatForever(SKAction.moveBy(x: -5000, y: 0, duration: 1.5)) 
... 

override func keyDown(with event: NSEvent) { 
    camera!.constraints = [] // remove constraints usually added by a cameraComponent. 

    let ekc = event.keyCode 
    if ekc == 123 { camera!.run(moveLeft, withKey: "moveLeft") } 
    if ekc == 124 { camera!.run(moveRight, withKey: "moveRight") } 
    if ekc == 126 { camera!.run(moveUp, withKey: "moveUp") } 
    if ekc == 125 { camera!.run(moveDown, withKey: "moveDown") } 

    print("keyDown: \(event.characters!) keyCode: \(event.keyCode)") 
} 


override func keyUp(with event: NSEvent) { 
    let ekc = event.keyCode 
    if ekc == 123 { camera!.removeAction(forKey: "moveLeft") } 
    if ekc == 124 { camera!.removeAction(forKey: "moveRight") } 
    if ekc == 126 { camera!.removeAction(forKey: "moveUp") } 
    if ekc == 125 { camera!.removeAction(forKey: "moveDown") } 
} 
Các vấn đề liên quan